Start learning free

LESSON 135 OF 677 · DICTIONARIES - CHALLENGES

Add a Contact in Scala

Practice Read the full explanation

You get a phone book phoneBook, a mutable.Map from names to phone numbers. You also get a name and a phone number.

Add name with its number to the phone book, and return the phone book.

Only add name when it isn't in the phone book yet. A name that is already there keeps its old number. The order of the entries doesn't matter.

 

Example 1:

Input: phoneBook = {"Ana": "555-0142", "Ben": "555-0199"}, name = "Cara", number = "555-0123"
Output: {"Ana": "555-0142", "Ben": "555-0199", "Cara": "555-0123"}
Explanation: "Cara" isn't in the phone book yet, so she is added.

Example 2:

Input: phoneBook = {"Ana": "555-0142", "Ben": "555-0199"}, name = "Ben", number = "555-0100"
Output: {"Ana": "555-0142", "Ben": "555-0199"}
Explanation: "Ben" is already in the phone book. He keeps his old number, "555-0199".

Example 3:

Input: phoneBook = {}, name = "Max", number = "555-0100"
Output: {"Max": "555-0100"}
Explanation: The phone book was empty. Now it has one contact.

 

Constraints:

  • phoneBook can be empty.
  • Names are single words made of English letters.
  • Every phone number has three digits, a dash and four digits, like "555-0142".
  • Two people can share a phone number.
STEP 1 OF 3
    Ctrl + Enter to check

    SCALA · DICTIONARIES - CHALLENGES

    Add Contact in Scala, explained

    Problem overview

    The method addContact gets a phone book, phoneBook, a scala.collection.mutable.Map[String, String] from names to phone numbers, plus a name and a phone number. It adds the name with its number and returns the phone book, but only when the name isn't a key yet. A name that is already there keeps its old number. The order of the entries doesn't matter.

    With {"Ana": "555-0142", "Ben": "555-0199"} and the new contact "Cara", "555-0123", the book gets a third entry. Adding "Ben" with "555-0100" changes nothing, because Ben already has "555-0199". An empty phone book plus "Max" gives a book with one contact.

    Approach

    Assigning to a key with phoneBook(name) = number adds the entry if the key is new, but it also replaces the value if the key exists. The task forbids that replacement, so the assignment must run only for a new name. phoneBook.contains(name) says whether the name is a key, and ! turns it around.

    Step by step

    1. Write an if on !phoneBook.contains(name). It is true only when the name is not a key yet. Close its brace right away and fill the body next.
    2. Inside it, assign phoneBook(name) = number. For a key that isn't there, this adds it with its value.
    3. After the if, return phoneBook. It has the new contact, or it is as it was.

    The solution in Scala

    class Solution {
        def addContact(phoneBook: scala.collection.mutable.Map[String, String], name: String, number: String): scala.collection.mutable.Map[String, String] = {
            if (!phoneBook.contains(name)) {
                phoneBook(name) = number
            }
            return phoneBook
        }
    }
    

    Details on the Scala:

    • phoneBook(name) = number is shorthand for phoneBook.update(name, number). It needs a mutable map; an immutable Map has no such operation.
    • contains looks only at the keys. Two people may share a number, and that is fine: numbers are values, not keys.
    • The method changes the map it receives and returns that same map.

    Another way

    Scala's mutable map has getOrElseUpdate(key, default). It returns the value for the key, and when the key is missing it stores the default first. So phoneBook.getOrElseUpdate(name, number) adds the contact only when the name is new, which is the same behaviour in one call. With the first two examples it gives Ana: 555-0142, Ben: 555-0199, Cara: 555-0123, and Ben keeps 555-0199 after getOrElseUpdate("Ben", "555-0100"). The lesson's version spells the check out with contains, which makes each step visible.

    Why the check matters

    Think of the phone book as a record of who was added first. Overwriting would silently lose the old number, and nothing in the program would say so. A check before every write is the cheap way to protect existing data: ask whether the key is there, and write only if the answer is no.

    Running it

    Results for the three examples, one entry per line, sorted by name (the order of entries in a map isn't fixed, so the lesson's tests don't depend on it):

    Cara added:
    Ana: 555-0142
    Ben: 555-0199
    Cara: 555-0123
    
    Ben again:
    Ana: 555-0142
    Ben: 555-0199
    
    Empty book, Max:
    Max: 555-0100
    

    Edge cases and common mistakes

    • Skipping the check. Without the if, phoneBook("Ben") = "555-0100" overwrites the old number. That is the main trap: the assignment looks safe, but for an existing key it replaces the value.
    • Forgetting !. The assignment then runs only for names already in the book, and a new name is never added.
    • An empty book. Nothing special is needed: contains is false, so the contact is added.
    • Checking the number. The test is on the name. Two contacts with the same number are both kept.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free