Cannot generate Range with end <start Check range before loop execution?
I encounter changes in fast code that I donโt quite understand.
var arr = [] for var i = 1; i <= arr.count; i += 1 { print("i want to see the i \(i)") } I have a program that gets an array of results, which can also be empty. This is not a problem with the for loop above. Now the apple wants me to change the code to the following. But this will crash if the array is empty.
var arr = [] for i in 1...arr.count { print("i want to see the i \(i)") } Do I need to check the range first before I do the loop?
var arr = [] if (arr.count >= 1){ for i in 1...arr.count { print("I want to see the i \(i)") } } Is there a smarter solution?
If you just want to iterate over the collection, use the syntax for <element> in <collection> .
for element in arr { // do something with element } If you also need access to the index of the element at each iteration, you can use enumerate() . Since indexes are zero-based, the index will have a range of 0..<arr.count .
for (index, element) in arr.enumerate() { // do something with index & element // if you need the position of the element (1st, 2nd 3rd etc), then do index+1 let position = index+1 } You can always add it to the index at each iteration to access the position (get range 1..<arr.count+1 ).
If none of these problems solves your problem, you can use range 0..<arr.count to iterate over the indices of your array or as @vacawama says you can use range 1..<arr.count+1 to iterate through positions .
for index in 0..<arr.count { // do something with index } for position in 1..<arr.count+1 { // do something with position } 0..<0 cannot fail for an empty array, since 0..<0 is just an empty range, and 1..<arr.count+1 cannot fail for an empty array, since 1..<1 also an empty range .
Also see @vacawama's comment below about using stride to safely perform additional custom ranges. For example (Swift 2 syntax):
let startIndex = 4 for i in startIndex.stride(to: arr.count, by: 1) { // i = 4, 5, 6, 7 .. arr.count-1 } Swift 3 Syntax:
for i in stride(from: 4, to: arr.count, by: 1) { // i = 4, 5, 6, 7 .. arr.count-1 } Here, startIndex is the number starting with the range, arr.count is the number that will remain lower, and 1 is the step length. If your array has fewer elements than the given start index, then the loop will never be entered.
The obvious solution in this case would be:
var arr = [] for i in arr.indices { print("I want to see the i \(i)") // 0 ... count - 1 print("I want to see the i \(i + 1)") // 1 ... count } but carefully read the originaluser2 review
This should lead to the same results as your first example, without errors ...
var arr = [] var i=1 for _ in arr { print("i want to see the i \(i)") i += 1 } ... although this just seems like a complicated way to count the elements in an array (arr.count), so I suspect this question is bigger than it seems at first glance.