What this lesson covers
A for (x in array) loop hands you each element but not its position. Sometimes you need both: to number the items, to compare neighbours, or to write into an array. Then you loop over the indices of the array and read each element with array[i].
The indices of an array start at 0 and end at size - 1. An array with four elements has the indices 0, 1, 2 and 3. A loop over exactly those values visits every element once.
The syntax
The range 0 until n contains the integers from 0 up to n - 1. The upper end is excluded, which is exactly the set of valid indices when n is the size:
val meals = arrayOf("pancakes", "pasta", "pizza", "avocado")
for (i in 0 until meals.size) {
println("Meal number ${i + 1} is ${meals[i]}.")
}
This prints:
Meal number 1 is pancakes.
Meal number 2 is pasta.
Meal number 3 is pizza.
Meal number 4 is avocado.
Three pieces are worth separating:
for (i in 0 until meals.size). Kotlin declaresifor you, with novaror type, and gives it the next value of the range on each pass.meals[i]. Square brackets read the element at indexi.${i + 1}. A string template inserts the value of any expression written between${and}. The index is 0-based and people count from 1, so the printed number isi + 1. For a plain variable,$namewithout braces is enough.
The exercise
The lesson gives you an array of daily temperatures and asks you to print one line per day in the form On day 1 the temperature is 10., with the day starting at 1. The code uses the same two ideas as the example above.
- Loop over the indices.
for (i in 0 until temperatures.size)makesitake the values 0, 1, 2 and 3 for this four-element array. - Print with a template. Inside the loop,
println("On day ${i + 1} the temperature is ${temperatures[i]}.")builds the line. The day isi + 1because days start at 1, and the temperature istemperatures[i]because arrays start at 0.
val temperatures = intArrayOf(10, 60, -5, 32)
for (i in 0 until temperatures.size) {
println("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 negative number needs no special care. The template converts the Int to text, with its minus sign, and the closing period comes from the template text itself.
Other ways to get the indices
temperatures.indices. It is the range0..size - 1made for you, sofor (i in temperatures.indices)visits the same values as0 until temperatures.sizeand is harder to get wrong.withIndex(). It pairs each element with its position, and a destructuring declaration unpacks the pair:for ((i, t) in temperatures.withIndex()). Hereiis the index andtthe temperature, so notemperatures[i]is needed.
The lesson uses until with size because it shows exactly where the bound comes from.
Common mistakes
- Going one past the end. With
0..temperatures.size, the range is inclusive, so the last value ofiis 4, andtemperatures[4]throwsArrayIndexOutOfBoundsExceptionwith the messageIndex 4 out of bounds for length 4. Useuntilfor an excluded end. - Using
0..size - 1carelessly. It is valid, since the range is inclusive and ends at the last index. For an empty array it becomes0..-1, which is an empty range, so it works too. Theuntilform avoids the subtraction. - Printing the index as the day. Without
+ 1, the output starts at "On day 0". - Forgetting the braces in a template.
"$temperatures[i]"inserts only the variabletemperatures(printed as an unreadable array reference), followed by the literal text[i]. Anything more than a name needs${...}. - Typing the trailing period wrong. The line ends with a period after the temperature, and the exact text matters to the lesson's tests.
Key takeaways
- Array indices run from 0 to
size - 1. 0 until nexcludesnand0..nincludes it. For array indices, useuntilwithsize, or use.indices.- Read an element with
array[i]. - Insert expressions in strings with
${...}. - Use an index loop when you need the position, and a plain
for (x in array)when you don't.