Start learning free

LESSON 135 OF 678 · DICTIONARIES - CHALLENGES

Add a Contact to a Swift Dictionary Without Overwriting

Practice Read the full explanation

You get a phone book phoneBook, a Dictionary 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 4
    Ctrl + Enter to check

    SWIFT · DICTIONARIES - CHALLENGES

    Add Contact in Swift, explained

    Problem overview

    The method addContact receives a phone book, a dictionary from names to phone numbers, plus a name and a number. It adds the name with its number and returns the phone book, but only when the name isn't in the book yet. A name that is already there keeps its old number. The order of the entries doesn't matter, and the book can be empty.

    Adding "Cara" with "555-0123" to a book with Ana and Ben gives a book with three contacts. Adding "Ben" with a new number changes nothing: Ben keeps "555-0199". Adding "Max" to an empty book gives a book with one contact.

    Approach

    Assigning to a dictionary key replaces the old value if the key exists, and adds the entry if it doesn't. That is exactly the behaviour we must prevent for existing names, so the assignment goes behind a check. A lookup of a missing key gives nil, so result[name] == nil means "this name is new".

    Step by step

    1. The parameter phoneBook is a constant. Copy it into a variable, var result = phoneBook. Assigning a dictionary copies it, so result starts with the same entries and can change.
    2. Write an if that checks result[name] == nil.
    3. Inside it, set result[name] = number. This adds the new entry.
    4. After the if, return result.

    The solution in Swift

    class Solution {
        func addContact(_ phoneBook: [String: String], _ name: String, _ number: String) -> [String: String] {
            var result = phoneBook
            if result[name] == nil {
                result[name] = number
            }
            return result
        }
    }
    

    Printing each result with the keys sorted, one key: value pair after another, gives these three lines for the examples:

    Ana: 555-0142, Ben: 555-0199, Cara: 555-0123
    Ana: 555-0142, Ben: 555-0199
    Max: 555-0100
    

    Language details

    • The lookup result[name] has type String?. Comparing it with nil needs no unwrapping.
    • Without the copy, phoneBook[name] = number would not compile, because function parameters are constants.
    • The caller's dictionary is not touched, since dictionaries are values and result is a separate copy.
    • Dictionary order is not stable, so a program that prints a dictionary should sort the keys first, as above. The lesson's tests do not depend on the order.

    Edge cases and common mistakes

    • Assigning without the check. result[name] = number on its own replaces Ben's number. Example 2 would then return "555-0100" for Ben, which is wrong.
    • Checking the number instead of the name. Two people can share a number, and the rule is about names. Look up name.
    • Returning the original. If you return phoneBook instead of result, the new contact is missing.
    • Empty book. No special case: the lookup is nil and the entry is added.

    Testing

    Try a book where the name is already there but its number is different, such as Ben with "555-0100". The result must still show "555-0199", as in the second example. Then try a number that another contact already has. Adding "Dan" with "555-0142" to a book that holds only Ana with that same number gives Ana: 555-0142, Dan: 555-0142: the new name is added anyway, because only names have to be unique.

    It also helps to call the method on a constant book and print that book afterwards. It is unchanged, because the method worked on its own copy.

    Keep going with Swift500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free