Index and bracket notation
Every element of an array has a numbered position, its index. Indexing is zero-based: the first element is at index 0, the second at index 1, and so on. To read an element, write the array's name followed by the index in square brackets.
val animals = arrayOf("cat", "dog", "parrot")
println(animals[0])
println(animals[1])
println(animals[2])
cat
dog
parrot
An array of 3 elements has valid indices 0, 1 and 2. There is no element at index 3, and asking for it stops the program with an exception, which a later lesson covers.
Elements are ordinary values
The expression animals[1] has the array's element type, here String. For an IntArray, ages[0] is a plain Int. That means you can use it anywhere an Int fits: in arithmetic, in a comparison, or as an argument to println.
val scores = intArrayOf(10, 20, 30)
println(scores[0] + scores[2])
40
Kotlin evaluates the expression inside the parentheses first, so println receives the finished number 40, not the pieces.
Why counting starts at zero
An index is best read as an offset: how many steps you are from the start of the array. The first element is zero steps from the start, so it is at index 0. The last element of an array with n items is n - 1 steps away. Thinking of the index as a distance, rather than as a place in a queue, makes off-by-one mistakes much less likely.
Elements and types
All the elements of an array have the same type, so the type of an indexed read is known before the program runs. In arrayOf("cat", "dog", "parrot") every read gives a String, and in an IntArray every read gives an Int. The compiler uses this to catch mistakes: storing the result of animals[0] in an Int variable doesn't compile.
The exercise
The starter code gives you two arrays:
val fruits = arrayOf("mango", "kiwi", "grapefruit")
val ages = intArrayOf(14, 32, 50, 21)
- Print the second fruit. The second item is at index 1, not 2, because counting starts at 0. This prints
kiwi. - Print the sum of the first three ages. Index each one, 0, 1 and 2, and add them inside the call: 14 + 32 + 50 prints
96. - Print the last age minus the first. The array has four elements, so the last index is 3. The difference 21 - 14 prints
7.
val fruits = arrayOf("mango", "kiwi", "grapefruit")
val ages = intArrayOf(14, 32, 50, 21)
println(fruits[1])
println(ages[0] + ages[1] + ages[2])
println(ages[3] - ages[0])
The output is:
kiwi
96
7
Reading is safe, but only inside the bounds
Reading an element never changes the array, so you can read the same index as many times as you like. The only thing to watch is that the index is valid. If the index comes from a calculation, such as ages.size - 1, check that the calculation can't produce a value below 0 or at least the size. Kotlin also offers getOrNull(index), which returns null instead of failing when the index is outside the array.
Common mistakes
- Off-by-one indexing. Asking for
fruits[2]when you want the second item returnsgrapefruit, the third. The Nth item is at index N - 1. - Using the size as an index. The last valid index is always the size minus one. For
ages, that is 3, not 4. - Forgetting that elements are values. To add two elements, add their indexed forms, as in
ages[0] + ages[1]. Adding the arrays themselves isn't what you want. - Using parentheses. Kotlin reads arrays with brackets:
ages[1], notages(1), which tries to callagesas a function and doesn't compile.
Visiting every element
Indexing becomes more useful with a loop. The property indices gives the range of valid positions, so a loop over it never goes out of bounds:
val animals = arrayOf("cat", "dog", "parrot")
for (i in animals.indices) {
println("$i: ${animals[i]}")
}
println(animals[2].length)
0: cat
1: dog
2: parrot
6
The last line shows that an element can be used like any other value of its type: animals[2] is a String, so you can ask for its length. A loop that only needs the values, not the positions, can write for (animal in animals) instead.
Key takeaways
- Indices start at 0 and end at size - 1.
array[i]reads the element at indexi.- An indexed element is an ordinary value and can be used in expressions.