Replacement for C-Style Loop in Swift 2.2

Replacement for C-style loop in Swift 2.2

Although it's not as "pretty", you can use stride:

for var i in 0.stride(to: -1, by: -1) {
print(i)
}

How to replace a complicated C-style for loop in Swift 2.2

The simplest solution is to just use a while loop:

Replace this code:

if bitsToWalk > 0 {
// Walk significant bits by shifting right until all bits are equal to 0.
for var bitsLeft = bitsToWalk; bitsLeft > 0; bitsLeft >>= 1 {
significantBitCount += 1
}
}

With the following while loop:

while bitsToWalk > 0 {
significantBitCount += 1
bitsToWalk >>= 1
}

Alternative for Swift C-style loop when iterator was changed conditionally within the loop

The iterator variable declared in a for loop is scoped to a single pass through that loop, so if you want to change it across multiple passes through the loop you'll need to use a while loop instead.

Also, since your intention seems to be "increment the loop counter only if checkCondition() is false" you can do that more clearly with a single, conditional increment, instead of using a decrement to undo your increment. Here are a couple of examples of that:

var i = 1
while i <= 10 {
if !checkCondition() {
i += 1
}
}

var j = 1
while j <= 10 {
j = checkCondition() ? j : j + 1
}

And a one that's maybe a little silly, but might come in handy if you do this sort of thing a lot:

extension IntegerType {
mutating func incrementIf(@autoclosure condition: () -> Bool) {
if condition() {
self = self + 1
}
}
}
var k = 1
while k <= 10 {
k.incrementIf(!checkCondition())
}

Of course, there's the further question of whether you want to be following this counter-based pattern at all (as @Sulthan notes in comments). Part of why Swift is doing away with the C-style for loop is that many loops with a counter are actually using that counter to index a collection, which is a pattern better served by collection iteration. So you might instead do something like:

for item in collection {
process(item)
if item.needsMoreProcessing {
process(item) // some more
}
}

for item in collection {
while item.needsProcessing {
process(item)
}
}

If something like this is what your loop is actually doing, writing it this way makes your purpose much more clear to other readers of your code (including your future self).

How to write a non-C-like for-loop in Swift 2.2+?

Worst case, you can convert it to a while loop.

var i = 0
var j = 1
while i <= array.count -2 && j <= array.count - 1 {
// something
i += 1
j += 1
}

-- EDIT --

Because you said, "while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop"... I feel the need to expand on my answer. I don't want to be responsible for a bunch of bad code...

In most cases, there is a simple for-in loop that can handle the situation:

    for item in array {
// do something with item
}

for (item1, item2) in zip(array, array[1 ..< array.count]) {
// do something with item1 and item2
}

for (index, item1) in array.enumerate() {
for item2 in array[index + 1 ..< array.count] {
// do soemthing with item1 and item2
}
}

For your last case, you might be justified using a for look, but that is an extremely rare edge case.

Don't litter your code with for loops.

Replace c style for-loop in Swift 2.2.1

Try this:

var i = column - 1
while i >= 0 && burgers[i, row]?.burgerType == burgerType {
i -= 1
horzLength += 1
}

This sort of abuse of the for loop syntax was the exact reason it was deprecated in Swift 2.2. Even if a for syntax was available, this would still be more clear than that abomination

#warning: C-style for statement is deprecated and will be removed in a future version of Swift

Removing for init; comparison; increment {} and also remove ++ and -- easily. and use Swift's pretty for-in loop

   // WARNING: C-style for statement is deprecated and will be removed in a future version of Swift
for var i = 1; i <= 10; i += 1 {
print("I'm number \(i)")
}

Swift 2.2:

   // new swift style works well
for i in 1...10 {
print("I'm number \(i)")
}

For decrement index

  for index in 10.stride(to: 0, by: -1) {
print(index)
}

Or you can use reverse() like

  for index in (0 ..< 10).reverse() { ... }

for float type (there is no need to define any types to index)

 for index in 0.stride(to: 0.6, by: 0.1) {
print(index) //0.0 ,0.1, 0.2,0.3,0.4,0.5
}

Swift 3.0:

From Swift3.0, The stride(to:by:) method on Strideable has been replaced with a free function, stride(from:to:by:)

for i in stride(from: 0, to: 10, by: 1){
print(i)
}

For decrement index in Swift 3.0, you can use reversed()

for i in (0 ..< 5).reversed() {
print(i) // 4,3,2,1,0
}

iOS Sample Image 46


Other then for each and stride(), you can use While Loops

var i = 0
while i < 10 {
i += 1
print(i)
}

Repeat-While Loop:

var a = 0
repeat {
a += 1
print(a)
} while a < 10

check out Control flows in The Swift Programming Language Guide

replacement for c-loop if the array may be nil for swift 2.2 and above

For your use case, the simplest solution is using an empty array instead of nil.

let currentLeft: [Int] = i < leftArr.count ? leftArr[i] : []
let currentRight: [Int] = i < rightArr.count ? rightArr[i] : []

Also, you might use a more functional approach:

currentLeft.forEach {
current.append($0)
}

or just:

let current = currentLeft + currentRight

Swift 2.2 decrementing specific for loop in Swift 3

Your code isn't counting the number of 3-letter words in the array. It is counting the number of 3-letter words at the end of the array. It will return 0 for your sample input array.

When a C-style for loop is very complex, the final fallback solution is to translate it to a while loop. Any C-style for loop can be mechanically converted into an equivalent while loop, which means you can do it even if you don't fully understand what it is doing.

This for loop:

for initialization; condition; increment {
// body
}

is equivalent to:

initialization
while condition {
// body
increment
}

So, your code is equivalent to:

let array = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]
var threeLetterWords = 0

var i = array.count - 1
while i >= 0 && array[i]?.characters.count == 3 {
i -= 1
threeLetterWords += 1
}
print("Found words: \(threeLetterWords)") // says `Found words: 0`

Here is how to use a for loop and guard to do the equivalent of your code:

let array = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]
var num3LetterWords = 0

for word in array.reversed() {
guard word?.characters.count == 3 else { break }
num3LetterWords += 1
}

print(num3LetterWords)


Related Topics



Leave a reply



Submit