What an index is
Every character in a Scala string has a position, called its index. Counting starts at 0, so the first character is at index 0, the second at index 1, and so on. A string of length n has valid indexes from 0 to n - 1.
Whitespace counts like any other character. In "Hello world!" the space sits at index 5, between o at index 4 and w at index 6.
Two ways to read a character
A Scala String is a Java string, so it has the Java method charAt. Scala also lets you put the index in parentheses right after the string, as if the string were a function:
val message = "Hello world!"
println(message.charAt(0)) // H
println(message(0)) // H
println(message(6)) // w
Both forms give the same result, a value of type Char. The parentheses form is the idiomatic one in Scala. It works because message(6) is shorthand for message.apply(6).
Because spaces have indexes too, you can see them by printing three neighbouring characters:
val message = "Hello world!"
println(s"${message.charAt(4)}${message.charAt(5)}${message.charAt(6)}")
o w
The exercise, step by step
The lesson gives you one value:
val fruit = "Avocado"
- Print the first character. The first position is index 0, so
fruit(0)is the character to print. - Print the last character.
"Avocado"has 7 characters, so the valid indexes are 0 to 6 and the last character isfruit(6).
Each println prints its character on its own line:
val fruit = "Avocado"
println(fruit(0))
println(fruit(6))
A
o
Finding the last character without counting
The number 6 above comes from counting by hand. That breaks as soon as the string changes. The last index is always length - 1, so this version works for any non-empty string:
val fruit = "Avocado"
println(fruit(fruit.length - 1)) // o
Scala's collection methods give shortcuts too: fruit.head is the first character and fruit.last is the last one. Both throw NoSuchElementException on an empty string.
Common mistakes
- Counting from 1.
fruit(1)is the second character,v, not the first. - Using
lengthas an index. For"Avocado",fruit(7)is one past the end and throws aStringIndexOutOfBoundsExceptionwith the messageIndex 7 out of bounds for length 7. - Negative indexes. Scala has no "count from the end" index.
fruit(-1)throws the same exception, with the messageIndex -1 out of bounds for length 7. - Square brackets. Scala uses parentheses for strings and arrays, so
fruit[0]does not compile. - Reading a
Charas a string.fruit(0)is aChar, written'A'with single quotes in code. Printing it shows justA.
Visiting every character
Once you know that indexes run from 0 to length - 1, a loop can visit each position. 0 until fruit.length stops before the length, so it never goes out of range:
val fruit = "Avocado"
for (i <- 0 until fruit.length) {
println(s"$i: ${fruit(i)}")
}
This prints 0: A, 1: v, 2: o and so on, up to 6: o. When you don't need the position, loop over the characters directly with for (c <- fruit) println(c).
A Char is not a String
Adding two characters does not join them. A Char behaves like a small number, so fruit(0) + fruit(1) is the Int 183, the sum of the codes of A and v. To join characters, convert one to a string first: fruit(0).toString + fruit(1) gives Av.
Key takeaways
- Indexes start at 0 and run to
length - 1. s(i)ands.charAt(i)both return theCharat positioni.- Spaces and punctuation have indexes too.
- The last character is
s(s.length - 1).
