Start learning free

LESSON 60 OF 414 · STRINGS I

String Length in Scala: length and the Last Characters

Lesson Read the full explanation

We can get the length of a string using the .length method like this:

var message = "Hello world"

// Printing the length:
println(message.length) // Output: 11

// Changing the message:
message += "!"

// Printing the new length:
println(message.length) // Output: 12

Accessing characters from the end:

The length is useful for accessing characters from the end of a string.

Because strings are 0-indexed, the index of the last character is length - 1:

var message = "Hello world"
var length = message.length

// Printing the last character:
println(message.charAt(length - 1)) // Output: d

// Printing the second to last character:
println(message.charAt(length - 2)) // Output: l

In general, if you want the nth last character, you use message.charAt(length - n).


Slicing characters from the end:

The length is also useful for slicing some characters from the end of a string:

var message = "Hello world"
var length = message.length

// Slicing last 4 characters:
var lastChars = message.substring(length - 4)
println(lastChars) // Output: orld

// Slicing last 7 characters:
lastChars = message.substring(length - 7)
println(lastChars) // Output: o world

In general, if you want the last n characters, you use message.substring(length - n).


Assignment
Follow the Coding Tutorial and let's practice with string length!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 3
    Ctrl + Enter to check

    SCALA · STRINGS I

    String Length in Scala, explained

    Getting the length

    The length method returns the number of characters in a string as an Int:

    var message = "Hello world"
    println(message.length) // 11
    
    message += "!"
    println(message.length) // 12
    

    Spaces and punctuation count. Because strings are immutable, message += "!" builds a new, longer string and stores it in the var, so the length is read from the new string. length is a Java method, so message.length() works too, and so does message.size.

    Counting from the end

    Indexes run from 0 to length - 1, so the last character is at length - 1. In general, the nth character from the end is at length - n:

    val message = "Hello world"
    val length = message.length
    
    println(message(length - 1)) // d
    println(message(length - 2)) // l
    

    The same idea gives the last n characters of a string: start the substring at length - n and run to the end.

    println(message.substring(length - 4)) // orld
    println(message.substring(length - 7)) // o world
    

    The exercise, step by step

    The lesson starts with val message = "I love pancakes", which has 15 characters.

    1. Print the length. message.length gives 15.
    2. Print the last character. Its index is message.length - 1, which is 14, so message(message.length - 1) is s.
    3. Print the last 5 characters. They start at index message.length - 5 (10) and end at the end of the string. The lesson passes the end explicitly: substring(message.length - 5, message.length). The one-argument form gives the same result.
    val message = "I love pancakes"
    
    println(message.length)
    println(message(message.length - 1))
    println(message.substring(message.length - 5, message.length))
    
    15
    s
    cakes
    

    Pitfalls

    • Off by one. The length is one more than the last index. message(message.length) throws a StringIndexOutOfBoundsException with the message Index 15 out of bounds for length 15.
    • Empty strings. For "" the length is 0, so s(s.length - 1) asks for index -1 and throws. Check s.nonEmpty first when the string might be empty.
    • Taking too many characters. substring(length - n) fails when n is larger than the length, because the start becomes negative. For short strings, takeRight(n) returns the whole string instead of throwing.
    • Characters versus code units. length counts 16-bit units. Most text is fine, but an emoji such as "😀" counts as 2.

    Empty strings and loops

    The empty string "" has length 0. Instead of comparing the length to 0, you can ask isEmpty or nonEmpty:

    println("".isEmpty)     // true
    println("ab".nonEmpty)  // true
    println("a b c".length) // 5
    

    The length also controls loops. for (i <- 0 until s.length) visits every index of s exactly once. Writing 0 to s.length would include the length itself, which is not a valid index.

    Why length - 1 and not length

    Counting and indexing start from different places. Counting starts at 1, so the last item is the nth. Indexing starts at 0, so the last item has index n - 1. For "I love pancakes", the answer to "how many characters?" is 15, but the answer to "where is the last one?" is 14. Keep these two questions apart and most index arithmetic becomes routine.

    Using the length in other calculations

    The length is an ordinary Int, so you can do arithmetic with it. Integer division truncates, so s.length / 2 is the index of the middle character of an odd-length string: for "abcde" it is 2, and "abcde"(2) is c. For an even length such as 4 it is 2, which is the right-hand one of the two middle characters. Always make sure the string is not empty before indexing with a value computed from its length.

    Key takeaways

    • s.length is the number of characters, and the last index is s.length - 1.
    • The last character is s(s.length - 1).
    • The last n characters are s.substring(s.length - n).
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free