Start learning free

LESSON 135 OF 679 · DICTIONARIES

Deleting a Key from a Rust HashMap

Lesson Read the full explanation

TL ; DR:

A HashMap's remove method takes a key. It deletes that key and its value.


let mut toys = HashMap::from([("ball", 3), ("doll", 2), ("kite", 1)]);

toys.remove("kite");

println!("{}", toys.len());   // 2


Full lesson:

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

Call remove on the map with the key. The key and its value go away together.

Deleting changes the map. So the map must be declared with let mut.

With a String key in a variable, pass a reference, as in remove(&name).

The length drops by 1. The key is gone, so toys.contains_key("kite") is now false.

remove also returns the deleted value inside an Option. Here that's Some(1). For a missing key it returns None, and nothing changes.

Watch out: after the delete, toys["kite"] panics and stops the program. Check with contains_key first.


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.len() 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

    RUST · DICTIONARIES

    Deleting Dictionary Keys in Rust, explained

    Removing an entry

    Sometimes an entry has to go: a shop stops selling an item, or a player leaves a game. A HashMap's remove method takes the key and deletes that key together with its value.

    let mut animals = HashMap::from([("cat", 4), ("dog", 2), ("rabbit", 1)]);
    animals.remove("rabbit");
    println!("{}", animals.len());   // 2
    

    Deleting changes the map, so it must be declared with let mut. Calling remove on a map declared without mut is a compile error: "cannot borrow b as mutable, as it is not declared as mutable". When the key is a String in a variable called name, pass a reference: remove(&name). (In a file of your own, a HashMap needs use std::collections::HashMap;.)

    What remove returns

    remove hands back the deleted value inside an Option. For the rabbit that is Some(1). For a key that isn't in the map it returns None, and the map doesn't change. So removing a key twice is harmless: the first call gives Some(1) and the second gives None, with two entries left. The lesson's task ignores the returned value, and Rust accepts that.

    After the delete

    The length drops by 1, and animals.contains_key("rabbit") becomes false. Reading animals["rabbit"] now panics and stops the program, so check with contains_key first if the key may be gone.

    The task, step by step

    The shop's animals map starts with cats, dogs and one rabbit, so the first line printed is the length, 3. The last rabbit just went home with a family. The first step deletes the key with animals.remove("rabbit"), below the first println!. The second step prints animals.len() again, which is one less: 2. The code at the bottom then checks the key, and since it is gone, it prints the "No rabbits left" message.

    let mut animals = HashMap::from([("cat", 4), ("dog", 2), ("rabbit", 1)]);
    println!("{}", animals.len());
    animals.remove("rabbit");
    println!("{}", animals.len());
    if animals.contains_key("rabbit") {
        println!("We still have rabbits");
    } else {
        println!("No rabbits left");
    }
    

    It prints:

    3
    2
    No rabbits left
    

    Removing a key that may be missing

    Because remove returns None for a key that isn't there and leaves the map alone, you don't need a contains_key check before it. You only need the check when you want to do something different depending on whether the key existed. If you do want that, the return value tells you: Some(1) means a rabbit entry existed with count 1, and None means there was nothing to remove. Compare that with indexing, where a missing key stops the program. Deleting is forgiving, and reading with [] is not.

    Order of the printed lines

    The task's output has three lines because the program does three things in order: print the length before the delete, delete, print the length after, then run the final check. The first number is 3 because the map has three keys. Remove does not make the other entries move or change; cat still has 4 and dog still has 2. Only the entry whose key you passed is gone, and the length is the count of keys left.

    Common mistakes

    • Declaring the map with let instead of let mut.
    • Passing the value (1) to remove. It wants the key.
    • Reading the key with [] after deleting it.

    Key takeaways

    • map.remove(key) deletes the key and its value, and needs a mut map.
    • It returns Some(value) for a present key and None for a missing one.
    • After a delete, len() is one less and contains_key is false.
    Keep going with Rust500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free