Start learning free

LESSON 131 OF 678 · DICTIONARIES

Deleting a Key from a Swift Dictionary

Lesson Read the full explanation

TL ; DR:

removeValue(forKey:) deletes a key and its value from a dictionary.


var toys = ["ball": 3, "doll": 2, "kite": 1]
toys.removeValue(forKey: "kite")

print(toys.count)   // 2


Full lesson:

Sometimes an entry has to go. A shop stops selling an item. A player leaves the game.

Call removeValue(forKey:) on the dictionary with the key. The key and its value go away together.

The count drops by 1. The key is gone, so toys["kite"] is now nil.

It also returns the deleted value, as an optional. For a missing key it returns nil, and nothing changes.

Setting a key to nil deletes it too, as in toys["kite"] = nil.

The dictionary must be a var. A let dictionary can't change.

Watch out: after the delete, toys["kite"]! crashes the program. There is no value left to unwrap.


Your task

A pet shop counts what it has for sale in animals. Each key is a kind of animal. Its value is how many the shop has.

The last rabbit just went home with a family. Delete the key "rabbit" from animals.

Then print animals.count again. The code at the bottom checks if any rabbits are left.

Expected output:

3
2
No rabbits left
STEP 1 OF 2
    Ctrl + Enter to check

    SWIFT · DICTIONARIES

    Deleting Dictionary Keys in Swift, explained

    removeValue(forKey:)

    Sometimes an entry has to go: a shop stops selling an item, or a player leaves the game. In Swift you call removeValue(forKey:) on the dictionary. The key and its value are deleted together, and the count drops by 1.

    var animals = ["cat": 4, "dog": 2, "rabbit": 1]
    animals.removeValue(forKey: "rabbit")
    print(animals.count)
    print(animals["rabbit"] == nil)
    
    2
    true
    

    The dictionary must be a var. For a let dictionary the compiler stops with cannot use mutating member on immutable value: 'd' is a 'let' constant, where d is the dictionary's name.

    What it returns

    The method returns the deleted value, as an optional. You can keep it, or ignore it as the code above does. For a key that isn't there it returns nil and nothing changes, and it doesn't crash.

    var pets = ["cat": 4, "dog": 2, "rabbit": 1]
    let removed = pets.removeValue(forKey: "rabbit")
    print(removed as Any, pets.count)
    print(pets.removeValue(forKey: "horse") as Any, pets.count)
    
    Optional(1) 2
    nil 2
    

    Assigning nil to a key deletes it too: animals["rabbit"] = nil. The result is the same, and it is handy when you don't need the old value.

    Order does not matter

    A dictionary has no first or last entry that you control, so there is no position to worry about, unlike removing from an array. Printing a whole dictionary may show its entries in any order, and the order can differ from one run to the next. Rely on keys only, never on where an entry sits.

    Deleting safely

    Because deleting a missing key does nothing, you don't have to check first. This is safe whether or not a rabbit is there:

    var animals = ["cat": 4, "dog": 2, "rabbit": 1]
    animals.removeValue(forKey: "rabbit")
    animals.removeValue(forKey: "rabbit")
    print(animals.count)
    animals["dog"] = nil
    print(animals)
    
    2
    ["cat": 4]
    

    The second call finds nothing and leaves the dictionary alone. Then animals["dog"] = nil deletes the dog entry too, so only the cat is left. Check first only when you need to react differently, for example to print a message.

    Traps

    • Using the key afterwards with !. After the delete, animals["rabbit"]! crashes the program, because there is no value to unwrap. Check for nil first.
    • Expecting the count to stay the same. The count is one less after a successful delete.
    • Deleting by value. Only keys can be deleted this way. To remove every entry holding a certain value you would need to find the keys first.
    • Keys must match exactly, so "Rabbit" would not delete "rabbit".

    The exercise: the last rabbit

    A pet shop keeps animals, where each key is a kind of animal and each value is how many the shop has. The starter code prints the count and then checks whether any rabbits are left. The last rabbit has just gone home with a family, so delete the key, and print the count again:

    var animals: [String: Int] = ["cat": 4, "dog": 2, "rabbit": 1]
    print(animals.count)
    animals.removeValue(forKey: "rabbit")
    print(animals.count)
    if animals["rabbit"] != nil {
        print("We still have rabbits")
    } else {
        print("No rabbits left")
    }
    

    The first print shows 3 keys. After the delete there are 2. The check at the bottom looks up "rabbit", gets nil, and takes the else branch:

    3
    2
    No rabbits left
    

    The delete line has to come after the first print and before the second, so the two counts show the change.

    Key takeaways

    • removeValue(forKey:) deletes a key and its value, and returns the old value or nil.
    • The dictionary must be a var.
    • Setting a key to nil deletes it as well.
    • Never force-unwrap a key you just deleted.
    Keep going with Swift500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free