How do I write a for-loop in Swift 3 for an array that I modify during the for loop?

So, I have a for-loop that looks similar to this:

for var i = 0; i < results.count ; i += 1 { if (results[i] < 5) { results.removeAtIndex(i) i -= 1 } } 

This used to work. But when I changed it to the preferred Swift 3.0 syntax:

for var i in 0..<results.count { if (results[i] < 5) { results.removeAtIndex(i) i -= 1 } } 

I get an array IOOBE exception because it doesn't re-check the count and continues on until the original results.count.

How do I fix this? It works now, but I don't want to get into trouble in the future.

2

4 Answers

While the solution making use of filter is a fine solution and it's more Swift-ly, there is another way, if making use of for-in is, nonetheless, still desired:

func removeBelow(value: Int) { var results = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] for i in (0 ..< results.count).reversed() { if (results[i] < value) { results.remove(at: i) } } print(results) } removeBelow(value: 5) 

Result:

[5, 6, 7, 8, 9, 10] 

The problem with removeAtIndex within the loop is that it will not cause the array to re-index itself in-place and thus causing an array out of bounds exception due to count not being updated.

By traversing backwards, the out of bounds exception can thus be avoided.

4

Could you use a filter instead?

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] let greaterThan4 = numbers.filter{$0 >= 5} print(greaterThan4) 
2

If you want to continue using a for-loop, you can enumerate over both index and element using enumerate:

for (index, element) in results.enumerate() { if (element < 5) { results.removeAtIndex(index) } } 

Although depending on what you're doing in your loop, the filter method might be a better idea.

1

If your loop goes forward...

for var i in (0..<results.count) where results.indices.contains(i) { //if the index doesn't exist, the loop will be stopped. if (results[i] < 5) { results.removeAtIndex(i) } } 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like