Start learning free

LESSON 107 OF 415 · DICTIONARIES

Accessing Dictionary Values in Swift: Optionals and Defaults

Lesson Read the full explanation

In Swift, you access values in a Dictionary using subscript notation dict[key]:

var scores = [String: Int]()
scores["Alice"] = 95
scores["Bob"] = 87

let aliceScore = scores["Alice"]!  // 95
let bobScore = scores["Bob"]!      // 87

If the key doesn't exist, subscript access returns nil. Use the [key, default:] subscript to provide a fallback:

let score = scores["Diana", default: 0]  // returns 0 if not found

Check if a key exists with optional binding:

if let score = scores["Alice"] {
    print(score)
}

Assignment
Follow the Coding Tutorial and access Alice's score from scores!


Hint
Use scores["Alice"]! and assign it to aliceScore.

STEP 1 OF 1
    Ctrl + Enter to check

    SWIFT · DICTIONARIES

    Accessing Dictionary Values in Swift, explained

    A lookup returns an optional

    You read a value from a dictionary with the same subscript you use to write one: dict[key]. The key might not be in the dictionary, so the result is not a plain value but an optional. For a [String: Int] the lookup has the type Int?. It holds the value when the key exists and nil when it does not.

    var scores = [String: Int]()
    scores["Alice"] = 95
    scores["Bob"] = 87
    
    print(scores["Alice"] as Any)
    print(scores["Diana"] as Any)
    print(type(of: scores["Alice"]))
    
    Optional(95)
    nil
    Optional<Int>
    

    Swift never returns a made-up value for a missing key and never crashes on the lookup. It hands you a nil and leaves it to you to handle it.

    Three ways to get the plain value

    Force unwrapping with !

    A ! after the lookup turns the optional into a plain Int:

    let aliceScore = scores["Alice"]!
    print(aliceScore + 1)
    
    96
    

    This is only safe when you know the key is present. If it is missing, the program crashes at run time. Use ! for keys you have just inserted or can otherwise vouch for.

    A default value

    The subscript form scores["Diana", default: 0] returns the stored value, or the default when the key is missing. The result is a plain Int, not an optional. The ?? operator does the same for an optional:

    print(scores["Diana", default: 0])
    print(scores["Diana"] ?? -1)
    
    0
    -1
    

    A default does not add the key to the dictionary. It only decides what the expression evaluates to.

    Optional binding

    To run code only when the key exists, use if let:

    if let score = scores["Alice"] {
        print("Alice has \(score)")
    }
    if let score = scores["Diana"] {
        print("Diana has \(score)")
    } else {
        print("no score for Diana")
    }
    
    Alice has 95
    no score for Diana
    

    Inside the first block, score is a plain Int. This form also answers "does this key exist?" without risking a crash.

    Checking whether a key exists

    Since a missing key gives nil, you can compare the lookup with nil to test for a key. Two other properties give the whole collections: keys and values.

    print(scores["Alice"] != nil)
    print(scores["Diana"] != nil)
    print(scores.keys.sorted())
    
    true
    false
    ["Alice", "Bob"]
    

    A dictionary has no defined order, so scores.keys on its own may list the keys in any order. Calling sorted() makes the result predictable.

    Reading every value

    To read all the pairs, loop over the dictionary and unpack each pair into a key and a value. Sorting by key makes the order predictable:

    for (name, score) in scores.sorted(by: { $0.key < $1.key }) {
        print("\(name): \(score)")
    }
    
    Alice: 95
    Bob: 87
    

    In the loop, name and score are already plain values, so no unwrapping is needed.

    The exercise

    The starter code gives a dictionary named scores with three students. The lesson asks for one step:

    1. Below the dictionary, declare a constant aliceScore and assign it scores["Alice"]!. The lookup returns an Int?, and the ! unwraps it to an Int. This is safe because "Alice" is in the dictionary.
    let scores: [String: Int] = ["Alice": 95, "Bob": 87, "Charlie": 72]
    
    let aliceScore = scores["Alice"]!
    

    After this, aliceScore is 95. Because scores is a let, the dictionary is read-only here, which is fine for a lookup.

    Common mistakes

    • Forgetting the optional. let n: Int = scores["Alice"] does not compile, because the right side is an Int?.
    • Force-unwrapping a missing key. scores["Zed"]! crashes. Prefer if let or a default when the key may be absent.
    • Misspelling the key. Keys are case-sensitive, so "alice" is a different key from "Alice" and the lookup gives nil.

    Key takeaways

    • dict[key] returns an optional, nil for a missing key.
    • Use ! only for keys that must exist, ?? value or [key, default:] for a fallback, and if let to branch on presence.
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free