The length property
Every Scala Array knows how many elements it holds. You get that count with .length:
val ourArray = Array(50, 40, 30)
println(ourArray.length) // 3
The length is the number of elements, not the highest index. Because indexes start at 0, an array of 3 elements has indexes 0, 1 and 2. The length of an array never changes after it is created, and an empty array has length 0. Arrays also respond to .size, which returns the same number.
Using the length to reach the end
Since the last index is always length - 1, you can read items from the end without knowing how many there are:
val ourArray = Array(50, 40, 30)
println(ourArray(ourArray.length - 1)) // 30
println(ourArray(ourArray.length - 2)) // 40
The expression ourArray.length - 1 is computed first and gives 2, so the outer call reads ourArray(2). Subtracting 2 gives the second to last item. The same code works for an array of any length, as long as it has enough elements.
The exercise
The lesson starts with:
val fruits = Array("mango", "kiwi", "grapefruit")
val ages = Array(14, 32, 50, 21)
Step 1: print the length of fruits
println(fruits.length) prints 3, the number of fruits.
Step 2: print the last element of ages
The array has 4 elements, so the last index is ages.length - 1, which is 3. println(ages(ages.length - 1)) prints 21.
Step 3: print the second to last element
One position before the last is ages.length - 2, index 2. println(ages(ages.length - 2)) prints 50.
The finished program
val fruits = Array("mango", "kiwi", "grapefruit")
val ages = Array(14, 32, 50, 21)
println(fruits.length)
println(ages(ages.length - 1))
println(ages(ages.length - 2))
It prints:
3
21
50
Length in loops
The length is also the natural bound for a loop over an array. The range 0 until ages.length starts at 0 and stops before the length, so every index it produces is valid:
for (i <- 0 until ages.length) {
print(ages(i) + " ")
}
This prints 14 32 50 21 . Because the loop reads ages.length and not a typed-in 4, it keeps working when the array has a different number of elements. Using 0 to ages.length instead would include the length itself as an index and stop the program with an exception on the last pass.
Gotchas
- Length is not an index.
ages(ages.length)is one past the end and throws anArrayIndexOutOfBoundsExceptionwith the messageIndex 4 out of bounds for length 4. That mistake is the subject of the next lesson. - Empty arrays. For an array with no elements,
length - 1is-1, and reading index -1 throws too. Checklength > 0first if the array might be empty. - Brackets for indexing.
ages[ages.length - 1]is a compile error. Use parentheses.
Length versus the number of items you filled in
The length counts slots, not meaningful values. An array created with new Array[Int](20) has length 20 even though every slot holds the default 0. A string array from new Array[String](5) also has length 5 while all five entries are still null. When you read length, you learn how many positions exist, and it is up to your program to know which of them hold real data.
This is also why the length of an array stays the same when you assign to its elements. ages(0) = 100 replaces a value, and ages.length is still 4 afterwards. Only creating a new array can give you a different length.
Key takeaways
array.lengthis the number of elements.- The last valid index is
array.length - 1. - Use
length - 2for the second to last,length - 3for the third to last, and so on.
