Why loop over indices
The usual way to visit every element of an array is for x in array. It gives you each value but not its position. When you need the position too, for example to print "day 3" next to the third value, to compare an element with its neighbour, or to return where something was found, you loop over the indices instead.
Indices and the half-open range
An array with count elements has valid indices from 0 to count - 1. The range 0..<array.count describes exactly these indices: the ..< operator includes the lower bound and stops before the upper one.
let meals = ["pancakes", "pasta", "pizza", "avocado"]
for i in 0..<meals.count {
print("Meal number \(i + 1) is \(meals[i]).")
}
The output is:
Meal number 1 is pancakes.
Meal number 2 is pasta.
Meal number 3 is pizza.
Meal number 4 is avocado.
The loop variable i takes the values 0, 1, 2 and 3. It is used twice: as the subscript in meals[i] and in the arithmetic i + 1, which turns a zero-based index into a human-friendly position that starts at 1.
Inside a string literal, \( ... ) is string interpolation: Swift evaluates the expression between the parentheses and inserts the result into the text. It accepts any expression, so \(i + 1) and \(meals[i]) both work.
The exercise
The exercise starts with an array of temperatures:
let temperatures = [10, 60, -5, 32]
The program should print one line per day, in the form On day 1 the temperature is 10.. Two steps do it:
- Write the loop. Use
for i in 0..<temperatures.count, soiruns over every valid index oftemperatures. - Print inside it. Each pass prints the day number,
i + 1, and the temperature stored at indexi.
The complete program:
let temperatures = [10, 60, -5, 32]
for i in 0..<temperatures.count {
print("On day \(i + 1) the temperature is \(temperatures[i]).")
}
It prints:
On day 1 the temperature is 10.
On day 2 the temperature is 60.
On day 3 the temperature is -5.
On day 4 the temperature is 32.
The text must match exactly: the capital O, the spaces and the full stop at the end are all part of the expected output.
When to choose each loop
If the body only needs the values, for x in array is shorter and can't go out of range. Reach for the index loop when the position matters: printing numbered lines, comparing array[i] with array[i + 1], or returning where something was found. A loop over indices also lets you change the array in place, with an assignment such as scores[i] = 0 on a var array.
Common mistakes
- Using
...instead of..<. The loop0...temperatures.countincludes the index 4, which doesn't exist. Readingtemperatures[4]stops the program with an index-out-of-range error. - Printing
iinstead ofi + 1. The first line would say "day 0". - An empty array.
0..<0is an empty range, so the loop body never runs and nothing is printed. The closed form0...count - 1would be0...-1there, which is an invalid range and crashes the program. - Using the loop variable after the loop.
iexists only inside the loop.
Key takeaways
- Use
for i in 0..<array.countwhen you need the position of each element. - Valid indices run from 0 to
count - 1, and..<excludes its upper bound, which suits this exactly. array[i]reads the element, and\(expression)inserts values into a string.- Add 1 to an index when you show it as a position to people.
