Start learning free

LESSON 131 OF 677 · DICTIONARIES

Deleting a Key from a Kotlin MutableMap

Lesson Read the full explanation

TL ; DR:

A MutableMap's remove function takes a key. It deletes that key and its value.


val toys = mutableMapOf("ball" to 3, "doll" to 2, "kite" to 1)
toys.remove("kite")

println(toys.size)   // 2
println(toys)        // {ball=3, doll=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.

The size drops by 1. The key is gone, so "kite" in toys is now false.

remove also returns the value it deleted. For a missing key it returns null, and nothing changes.

The map is a val, and you can still delete from it. A val only stops you from giving toys another map.

Watch out: after the delete, toys["kite"] is null. So toys["kite"]!! would crash the program.


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.size 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

    KOTLIN · DICTIONARIES

    Deleting Dictionary Keys in Kotlin, explained

    remove takes a key

    Sometimes an entry has to go: a shop stops selling an item, a player leaves the game. On a MutableMap, remove(key) deletes the key together with its value.

    val animals = mutableMapOf("cat" to 4, "dog" to 2, "rabbit" to 1)
    animals.remove("rabbit")
    println(animals.size)
    println(animals)
    println("rabbit" in animals)
    
    2
    {cat=4, dog=2}
    false
    

    The size drops by 1, and the key is no longer found by in.

    What remove returns

    remove gives back the value it deleted, so you can use it one last time. For a key that isn't in the map it returns null and changes nothing, and it does not throw.

    val removed = animals.remove("cat")
    println(removed)
    println(animals.remove("fish"))
    println(animals)
    
    4
    null
    {dog=2}
    

    Note that the return type is nullable (Int?), which is why a missing key can give null.

    val does not mean frozen

    animals is a val, and you can still delete from it. A val only stops you from pointing the name at another map; the map itself is a mutable object that can change. Writing animals = mutableMapOf("dog" to 1) on a val is what the compiler rejects, with 'val' cannot be reassigned.

    Shorter forms

    • animals -= "dog" removes a key too. It is the same as animals.remove("dog") without using the result.
    • animals.clear() removes every entry. The size is 0 afterwards and isEmpty() is true.

    Traps

    • Reading a deleted key. After the delete, animals["rabbit"] is null, so animals["rabbit"]!! crashes the program. Check with in first.
    • Deleting while looping. Calling remove inside a for loop over the same map's keys throws a ConcurrentModificationException. Collect what to delete first, or use map.keys.removeAll { ... } after the loop.
    • Value, not key. remove works on keys. Removing "the animal with count 1" means finding its key first.

    Only delete what is there

    Since remove on a missing key is harmless, you rarely need a check before it. If you want to act only when something was really removed, test the result or ask first:

    val a = mutableMapOf("cat" to 4, "dog" to 2)
    if ("dog" in a) a.remove("dog")
    println(a)
    
    {cat=4}
    

    There is also a two-argument form, remove(key, value), which deletes the entry only when the key currently holds that value. On {cat=4, dog=2}, remove("cat", 9) returns false and changes nothing, while remove("cat", 4) returns true and removes it.

    The exercise

    The starter code prints the size, then checks whether "rabbit" is still in the map. The last rabbit went home, so step 1 deletes the key below the first println, and step 2 prints animals.size again. The first line shows 3 and the second shows 2, and the check at the bottom now finds no rabbit key.

    val animals = mutableMapOf("cat" to 4, "dog" to 2, "rabbit" to 1)
    println(animals.size)
    animals.remove("rabbit")
    println(animals.size)
    if ("rabbit" in animals) {
        println("We still have rabbits")
    } else {
        println("No rabbits left")
    }
    
    3
    2
    No rabbits left
    

    The check at the bottom of the starter code does not change. It runs after the delete, asks "rabbit" in animals, gets false and takes the else branch. If you forget the delete, the same code prints We still have rabbits and the size line shows 3 twice, which is a quick way to see that the step is missing.

    Key takeaways

    • remove(key) deletes the key and its value, and the size drops by 1.
    • It returns the old value, or null for a missing key.
    • A val map can still lose entries.
    • After a delete, reading the key gives null.
    Keep going with Kotlin500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free