Swift Alternatives to C-style for-loops
Starting in Swift 3.0, C-style for-loops will be gone from Swift! You can read the full Swift Evolution proposal here.
Last week, I talked to an iOS developer who was upset by this (it is a long-held habit after all!) and was confused by what to use as an alternative. @twostraws did a great write-up on the new Swift 2.2 features and what to use instead, so I’m going to write it down here for my own (and your) reference.
Here are the more-readable Swift alternatives.
Looping n times
1 2 3 4 5 6 7 8 9 10 11 |
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 */ // Instead of this: for var i = 0; i < 10; i++ { print(i) } // use this: for i in 0..<10 { print(i) } |
Looping n times in reverse
1 2 3 4 5 6 7 8 9 10 11 |
/* 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 */ // instead of this for var i = 10; i > 0; i-- { print(i) } // use this for i in (1...10).reverse() { print(i) } |
Looping with Stride
1 2 3 4 5 6 7 8 9 10 11 |
/* 0, 2, 4, 6, 8 */ // instead of this for var i = 0; i < 10; i += 2 { print(i) } // use this for i in 0.stride(to: 10, by: 2) { print(i) } |
Looping through Array Values
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
let someNumbers = [2, 3, 45, 6, 8, 83, 100] /* 2, 3, 45, 6, 8, 83, 100 */ // instead of this for var i = 0; i < someNumbers.count; i++ { print(someNumbers[i]) } // use this for number in someNumbers { print(number) } // or this someNumbers.forEach { number in print(number) } |
Reverse Looping through Array Values
1 2 3 4 5 6 7 8 9 10 11 12 13 |
let someNumbers = [2, 3, 45, 6, 8, 83, 100] /* 100, 83, 8, 6, 45, 3, 2 */ // instead of this for var i = someNumbers.count - 1; i >= 0; i-- { print(someNumbers[i]) } // use this for number in someNumbers.reverse() { print(number) } |
Looping Through an Array with Index
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
let someNumbers = [2, 3, 45, 6, 8, 83, 100] /* 1: 2 2: 3 3: 45 4: 6 5: 8 6: 83 7: 100 */ // instead of this for var i = 0; i < someNumbers.count; i++ { print("\(i + 1): \(someNumbers[i])") } // use this for (index, number) in someNumbers.enumerate() { print("\(index + 1): \(number)") } // or this someNumbers.enumerate().forEach { (index, number) in print("\(index + 1): \(number)") } |
Looping Through Array Indices
Thanks Pyry Jahkola for the tip in the comments!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
let someNumbers = [2, 3, 45, 6, 8, 83, 100] /* 0, 1, 2, 3, 4, 5, 6 */ // instead of this for var i = 0; i < someNumbers.count; i++ { print(i) } // use this for index in someNumbers.indices { print(index) } |
Don’t Forget Higher Order Functions!!!
I won’t go into detail here, but instead of looping, consider if Swift’s higher order functions such as map, flatMap, filter, reduce, etc can do the job and prioritize using them instead!
Conclusion
I tend to use pretty simple for-loops, so these seem good enough for me. However, if you have another configuration that I’m missing, let me know in the comments!