Start learning free

LESSON 57 OF 414 · STRINGS I

Accessing Characters in Scala: Indexing Strings

Lesson Read the full explanation

Each character in a string has a numbered position known as its index. We access a character by referring to its index number.

Strings use zero-based indexing, so the first character in a string has an index of 0, the second character has an index of 1, etc.

We’re using the .charAt() method with the index to access the character:

val message = "Hello world!"

var c = message.charAt(0)
println(c) // Output: H

c = message.charAt(1)
println(c) // Output: e

println(message.charAt(6)) // Output: w

Whitespaces have indices:

Note that every character inside the quotes (including whitespaces) is part of the string and has its own index. For example, in string "Hello world!", the whitespace is placed on index 5.

You can see that clearly when you run this code:

val message = "Hello world!"

println(s"${message.charAt(4)}${message.charAt(5)}${message.charAt(6)}")

the output is:

o w

Assignment
Follow the Coding Tutorial and let's access some characters!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · STRINGS I

    Accessing Characters in Scala, explained

    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"
    
    1. Print the first character. The first position is index 0, so fruit(0) is the character to print.
    2. Print the last character. "Avocado" has 7 characters, so the valid indexes are 0 to 6 and the last character is fruit(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 length as an index. For "Avocado", fruit(7) is one past the end and throws a StringIndexOutOfBoundsException with the message Index 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 message Index -1 out of bounds for length 7.
    • Square brackets. Scala uses parentheses for strings and arrays, so fruit[0] does not compile.
    • Reading a Char as a string. fruit(0) is a Char, written 'A' with single quotes in code. Printing it shows just A.

    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) and s.charAt(i) both return the Char at position i.
    • Spaces and punctuation have indexes too.
    • The last character is s(s.length - 1).
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free