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?

+5
source share
3 answers

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.

+11
source

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

+3
source

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.

+1
source

All Articles