Ask Erica: How do I loop from non-zero n? #swiftlang

Mike T. writes: I have a for loop, but I deisre to start loop through array at index i (say “5”) instead of begining of the array

Swift 2.0 provides a basic C-like for loop, which is a good place to start:

for var index = 5; index < array.count; index++ {
  // do something with array[index]
}

You can do something fairly similar with ranges:

for index in 5..<array.count {
 // do something with array[index]
}

Or even:

(5..<array.count).forEach {
    // do something with array[$0]
}

You can also slice the array, which enables you to enumerate just that section you’re interested in, retrieving both the array index (offset by 5 in this example, as the slice’s enumeration starts its index count at 0) and its value at one go.

for (index, value) in array[5..<array.count].enumerate() {
  // do something with (index + 5) and/or value
}

If you want a more accurate count without having to offset by 5, use zip, as in the next example.

let range = 5..<array.count
for (index, value) in zip(range, array[range]) {        
    // use index, value here
}

You can also tweak this zip approach with forEach

let range = 5..<array.count
zip(range, array[range]).forEach {
    index, value in
    // use index, value here
}

Of course, you can also map the values if what you’re trying to do is transform each member of the subrange. Unlike forEach, map returns a new value after applying it within a closure.

let results = array[range].map({
    // transform $0 and return new value
})

If you just want to drop the first n values and start from there, use dropFirst(). This doesn’t get you the index but you can use any of the previous approaches to get it.

for value in array.dropFirst(5) {
    // use value here
}

Using removeFirst() returns the first element as well as removing it from the slice. This next snippet combines removeFirst() with dropFirst() to push past the first n items and then process one at a time.

var slice = array.dropFirst(5)
while !slice.isEmpty {
    let value = slice.removeFirst()
    // use value here
}

There are a bunch more ways to iterate, including delaying evaluation until the sliced values are actually needed (see lazy) but these are probably enough to get you started.

Thanks Mike Ash and make sure to check out Nate Cook’s solution

Comments are closed.