A Concise Way to Not Execute a Loop Now That C-Style for Loops Are Going to Be Removed from Swift 3

A concise way to not execute a loop now that C-Style for loops are going to be removed from Swift 3?

To do this in a way that works for n < 2, you can use the stride method.

let startIndex = 2
let endIndex = n

for i in stride(from: startIndex, through: endIndex, by: 1) {
memo.append(memo[i-1] + memo[i-2])
}

How to fix C-style for statement has been removed in Swift 3?

I don't think this can be written using for anymore, but you can use while loop to get the job done:

var nSize = merkleTree.count
while nSize > 1 {
// loop body

nSize = (nSize + 1) / 2
}

I would expect stride not to work in this case, because as your error states, you cannot use nSize as the stride parameter - nSize is iterating variable that gets declared based on the range, so you need the range to exist. At least that's my interpretation of the error (I know that theoretically you can generate range based on the previously generated item, but obviously stride does not work that way).

I believe you can find a way to generate a proper array of values using reduce (because I was able to, see below, maybe you can make it simpler), or by implementing your own stride that would accept a closure instead of a step (which would allow you to compute next item based on previous one), but both approaches are more complicated and obscure than using the simple while loop, so I personally prefer the while loop.

My not so nice reduce implementation (in result it uses an array and not a range, since by looking at NSRange I don't think you can create a range that does not step by 1):

let merkleTree = [1,2,3,4,5,6,7,8,9]

let numberOfDivisions = Int(log2(Double(merkleTree.count))) + 1
let startValue = merkleTree.count
let nSizes = (0..<numberOfDivisions).reduce([startValue]) { (result, next) -> [Int] in
var newResult = result
newResult.append((result.last! + 1) / 2)
return newResult
}
print(nSizes)
// and now you can for-in it:
for nSize in nSizes {
// ...
}

Fix warning C-style for Statement is deprecated in Swift 3

C-style for loop has been deprecated in Swift 3. You can continue using it for a while, but they will certainly disappear in the future.

You can rewrite your loop to Swift's style:

for i in 0..<len {
let length = UInt32 (letters.length)
let rand = arc4random_uniform(length)
randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}

Since you don't use i at all in the loop's body, you can replace it with:

for _ in 0..<len {
// do stuffs
}

c-style for statement deprecated with a twist

Might be best to go with a while loop:

var totalHeight: CGFloat = 0
while totalHeight < 2.0 * Configurations.sharedInstance.heightGame {
// Loop code goes here

totalHeight += backgroundImage.size.height
}

C-Style for loop works fine but changing to Swift for-in causes out of bounds errors

cheese.count is only being evaluated once. Suppose you start with 3 items in cheese. The loop will iterate over indices 0, 1, 2. If you remove item 1, then the old 2 becomes the new 1, and there is no longer an item at index 2. However, the loop will continue to index 2, just as it was set out to do from the beginning.

To fix this, every time you remove, deincrement your index:

for i in 0 ..< cheeses.count {
print(i) //prints just fine every time
if CGRectIntersectsRect(mouse.node.frame, cheeses[i].node.frame) {//throws the out of bounds error
cheeses[i].node.removeFromParent()
cheeses.removeAtIndex(i) //the culprit? ... no longer!
i -= 1 //fixed!
}
}

Now, that solves the error for the solution as you present it, but I propose a cleaner solution:

cheeses.filter{ cheese in
if CGRectIntersectsRect(mouse.node.frame, cheese.node.frame {
cheese.node.removeFromParent()
return false //don't keep this cheese
}
else {
return true //keep this cheese
}
}

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)
}

safely remove item while iterating backward in Swift 3

Use stride:

for i in stride(from: allowedItems.count - 1, through: 0, by: -1) {

}

Swift -How does a for loop finish before the line under it?

Fundamentally all operations are executed sequentially as stated in Oleg's answer.

What you have to understand is that special things like for loop statements or if statements or other, are sort of instructions for the runtime. And when the code executtion gets to the point where it encounters for loop instruction it goes on and on inside of a for loop. It just knows that this thing inside of for loop {} should be executed n times before it can continue. So when the for loop finishes, it goes to the next line of code and does whatever instruction is there.

This is not very deep explanation, but I was trying to be simplistic. Hope it helps.

New Swift for-in syntax for incrementing and decrementing loops

Why doesn't the Swift range operator handle decreasing ranges?

I believe I read a statement from a Swift team member (probably @jckarter) that they deliberately designed Range in this way to avoid a likely source of programmer errors. The reasoning was that more often than not, when you create a range from variables (not literals) like a..<b, you'd implicitly assume a <= b. Range is designed to trap if that assumption is violated to make the (possible) error obvious to you.

I can't find the reference at the moment though.



Related Topics



Leave a reply



Submit