Start learning free

LESSON 135 OF 671 · DICTIONARIES - CHALLENGES

Add a Contact to a Phone Book in Go

Practice Read the full explanation

You get a phone book phoneBook, a 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

    GO · DICTIONARIES - CHALLENGES

    Add Contact in Go, explained

    Problem overview

    The function addContact receives a phone book, phoneBook, which is a map[string]string from names to phone numbers, plus a name and a number. It adds the contact and returns the phone book, but only when name isn't in the phone book yet. A name that is already there keeps its old number.

    For a book with Ana and Ben and the new name Cara, the result has all three. For Ben with a new number, the result is unchanged, and Ben keeps 555-0199. For an empty book and Max, the result has one contact. The order of the entries doesn't matter: a Go map has no order of its own.

    Approach

    A plain assignment, phoneBook[name] = number, would add a missing name, but it would also overwrite an existing one. So first ask whether the name is a key. The comma-ok lookup answers that, and it is the right tool because it tells a missing key from a key that holds an empty string. Skip the value with _ and test !ok, which is true only for a new name.

    Step by step

    1. Write an if that looks name up with the comma-ok form and runs when ok is false. Put the lookup in the if line, before a ;.
    2. Inside it, store the number: phoneBook[name] = number. For a name already in the book nothing runs, so its old number stays.
    3. After the if, return phoneBook.

    The solution in Go

    func addContact(phoneBook map[string]string, name string, number string) map[string]string {
        if _, ok := phoneBook[name]; !ok {
            phoneBook[name] = number
        }
        return phoneBook
    }
    

    A map passed to a function is not copied: the function and its caller share the same map. The new contact therefore lands in the caller's map as well, and the returned value is that same map. After res := addContact(orig, "Max", "555-0100") on an empty orig, both len(orig) and len(res) are 1.

    Notice that the lookup and the assignment use the same key, name. Because the lookup sits in the if line, ok only exists for that statement. That keeps the check close to the code that depends on it and avoids a leftover variable.

    Testing

    Printing the returned map for the statement's examples gives:

    map[Ana:555-0142 Ben:555-0199 Cara:555-0123]
    map[Ana:555-0142 Ben:555-0199]
    map[Max:555-0100]
    

    Go's fmt prints maps sorted by key, so the output is stable, even though the map itself has no order.

    Edge cases and common mistakes

    • Skipping the check. With only phoneBook["Ben"] = "555-0100", Ben's number becomes 555-0100 and the old one is lost.
    • Checking with phoneBook[name] == "". It works while every stored number is non-empty, but it treats a stored empty string as missing, and it is the wrong habit for maps in general. The comma-ok form is exact.
    • An empty book. map[string]string{} works, and the lookup simply reports the name as missing. A nil map, declared as var m map[string]string, can be read but not written: adding a contact to it panics with assignment to entry in nil map. The lesson's tests pass real maps.
    • Same number for two people. Allowed. Only the names are keys.
    Keep going with Go500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free