Start learning free

LESSON 60 OF 415 · STRINGS I

String Length in Swift: count, last and suffix

Lesson Read the full explanation

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

var message = "Hello world"

// Printing the length:
print(message.count) // Output: 11

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

// Printing the new length:
print(message.count) // 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"
let length = message.count

// Printing the last character:
let lastIdx = message.index(message.endIndex, offsetBy: -1)
print(message[lastIdx]) // Output: d

// Printing the second to last character:
let secondLastIdx = message.index(message.endIndex, offsetBy: -2)
print(message[secondLastIdx]) // Output: l

In general, if you want the nth last character, you use message[message.index(message.endIndex, offsetBy: -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"
let length = message.count

// Slicing last 4 characters:
var lastChars = String(message.suffix(4))
print(lastChars) // Output: orld

// Slicing last 7 characters:
lastChars = String(message.suffix(7))
print(lastChars) // Output: o world

In general, if you want the last n characters, you use String(message.suffix(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

    SWIFT · STRINGS I

    String Length in Swift, explained

    Getting the length

    A Swift string reports its length through the count property. It counts characters, not bytes:

    var message = "Hello world"
    print(message.count)
    
    message += "!"
    print(message.count)
    
    11
    12
    

    It is a property, so there are no parentheses. The value follows the string: after += "!" the count is one higher. The empty string "" has a count of 0.

    Because count counts what a reader sees as one character, an accented letter or an emoji counts as 1 even though it takes several bytes to store:

    let text = "é🙂"
    print(text.count)
    print(text.utf8.count)
    
    2
    6
    

    Swift has to scan the string to find character boundaries, so count takes time proportional to the length. If you need it several times, store it in a constant.

    Reaching the end of a string

    Strings are numbered from 0, so the last character sits at offset count - 1. Swift has no integer subscript, so you move from endIndex, which points one past the last character, by a negative offset:

    let message = "Hello world"
    let lastIdx = message.index(message.endIndex, offsetBy: -1)
    print(message[lastIdx])
    
    let secondLastIdx = message.index(message.endIndex, offsetBy: -2)
    print(message[secondLastIdx])
    
    d
    l
    

    The nth character from the end is message[message.index(message.endIndex, offsetBy: -n)].

    The last property

    The simplest way to read the last character is the last property. It returns an optional, Character?, because an empty string has no last character:

    let word = "hello"
    print(word.last as Any)
    print(word.last!)
    
    let empty = ""
    print(empty.last as Any)
    
    Optional("o")
    o
    nil
    

    The ! force-unwraps the optional. It is fine when you know the string isn't empty, as in this lesson, but it crashes the program if the value is nil. When the string might be empty, use if let or a default with ?? instead.

    A safe way to read it is if let, which runs its block only when there is a value:

    let empty = ""
    if let ch = empty.last {
        print("last is", ch)
    } else {
        print("empty string")
    }
    
    empty string
    

    The length is also how you guard an index. Before you move to an offset, check it against count: an offset is safe only when it is at least 0 and less than message.count. Skipping that check on a string that might be short is the usual cause of a crash.

    The last n characters

    The suffix(n) method returns the last n characters:

    let message = "Hello world"
    print(message.suffix(4))
    print(message.suffix(7))
    print(message.suffix(100))
    
    orld
    o world
    Hello world
    

    If n is larger than the string, you get the whole string, with no crash. The result is a Substring, which prints like a string. Use String(message.suffix(4)) when you need to store it as a String.

    The exercise

    The string is "I love pancakes". Three steps, each printing one line:

    1. message.count gives the length. The string has 15 characters, spaces included.
    2. message.last! gives the last character, s.
    3. message.suffix(5) gives the last five characters, cakes.
    let message = "I love pancakes"
    
    print(message.count)
    print(message.last!)
    print(message.suffix(5))
    
    15
    s
    cakes
    

    Common mistakes

    • Using count as an index. The last valid offset is count - 1. Offsetting startIndex by count lands on endIndex, which isn't a character, and reading it crashes the program.
    • Writing count(). It is a property, not a method.
    • Forgetting the optional. last is a Character?. Without ! or if let, print shows Optional("s") rather than s.
    • Assuming bytes. The length of "é" is 1 in characters but 2 in utf8.count. Use count unless you really need bytes.

    Key takeaways

    • string.count is the number of characters.
    • string.last is an optional, nil for an empty string.
    • string.suffix(n) returns the last n characters as a Substring, and never crashes if n is too big.
    • The last valid offset in a string is count - 1.
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free