Start learning free

LESSON 129 OF 677 · DICTIONARIES

Checking for a Key in a Scala Map

Lesson Read the full explanation

TL ; DR:

Call map.contains(key) to ask whether a Map has a key. It returns true or false, so it goes in an if.


val capitals = scala.collection.mutable.Map("France" -> "Paris", "Japan" -> "Tokyo")

if (capitals.contains("Japan")) {
    println(capitals("Japan"))   // Tokyo
}

if (!capitals.contains("Spain")) {
    println("No Spain")          // No Spain
}


Full lesson:

Reading a missing key is an error. capitals("Spain") throws a NoSuchElementException.

So check first. capitals.contains("Spain") is true when "Spain" is a key. It is false when it isn't.

Put ! in front for the opposite. !capitals.contains("Spain") is true here.

A value is not a key

contains looks only at the keys. capitals.contains("Paris") is false, because "Paris" is a value.

A key must match exactly, upper and lower case too. capitals.contains("japan") is false.


Your task

In pets, each key is a pet's name, and its value is the pet's kind.

First, check whether "Tom" is a key of pets. If it is, print Tom is a followed by Tom's kind.

Then check that "cat" is not a key, with ! and contains. If so, print cat is not a key.

"cat" is in pets, but only as a value. It is Tom's kind.

Expected output:

Tom is a cat
cat is not a key
STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · DICTIONARIES

    Dictionary Key Check in Scala, explained

    Why check first

    A Map looks values up by key. Reading a key that isn't there is an error: with capitals = Map("France" -> "Paris", "Japan" -> "Tokyo"), the call capitals("Spain") throws java.util.NoSuchElementException: key not found: Spain. So when a key might be missing, ask first.

    contains(key) answers with a Boolean: true when the key is in the map, false when it isn't. That makes it a ready-made condition for an if.

    val capitals = scala.collection.mutable.Map("France" -> "Paris", "Japan" -> "Tokyo")
    if (capitals.contains("Japan")) {
        println(capitals("Japan"))   // Tokyo
    }
    if (!capitals.contains("Spain")) {
        println("No Spain")          // No Spain
    }
    

    Inside the first if, capitals("Japan") can't throw, because the check just proved the key is there. Put ! in front of contains for the opposite question: "is this key missing?"

    A value is not a key

    contains looks only at the keys. Here "Paris" is a value, so capitals.contains("Paris") is false. A key also has to match exactly, capital letters included: capitals.contains("japan") is false.

    Another way to ask

    get(key) returns an Option: capitals.get("Japan") is Some(Tokyo) and capitals.get("Spain") is None. It is the right tool when you want the value if it exists. When you only want a yes or no, contains says it directly.

    Check, then read

    The pattern in the first example is worth remembering: contains in the condition, map(key) in the body. The check protects the read. Code that reads without checking works for every key you tried and fails on the first one you didn't, which is how an exception shows up late. Another way is getOrElse, when a default value does the job.

    The same contains works on a Map that you can't change, such as one made with plain Map(...). The lesson uses a mutable one, so you can also add and delete entries later.

    The task

    In pets, each key is a pet's name and its value is the pet's kind. The task has two checks.

    1. If "Tom" is a key, print Tom is a followed by Tom's kind. Tom is a key, and his kind is "cat".
    2. If "cat" is not a key, print cat is not a key. The word "cat" is in the map, but only as Tom's value, so contains("cat") is false and the ! makes the condition true.
    val pets = scala.collection.mutable.Map("Rex" -> "dog", "Tom" -> "cat", "Polly" -> "parrot")
    if (pets.contains("Tom")) {
        println("Tom is a " + pets("Tom"))
    }
    if (!pets.contains("cat")) {
        println("cat is not a key")
    }
    

    It prints:

    Tom is a cat
    cat is not a key
    

    Two keys that look alike

    Keys are compared as whole values. With the pets map, "Tom" is a key but "Tom " with a trailing space is not, and "Tomas" is not either. If a lookup fails when the name looks right, print the key and check for stray spaces or different capitals.

    Common mistakes

    • Reading before checking. Writing pets("Sam") for a name that may be missing throws an exception and stops the program. Check with contains or use another lookup that handles a missing key.
    • Checking a value. pets.contains("cat") is a question about keys. It does not find the value "cat".
    • Case and spelling. "tom" and "Tom" are different keys.

    Key takeaways

    • map.contains(key) is true when the key is in the map and false otherwise.
    • Reading a missing key with map(key) throws, so check first when it might be absent.
    • Only keys count: a value is not found by contains.
    • !map.contains(key) asks whether the key is missing.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free