Introduction

Welcome! Today, we'll explore building a simple address book application using Go and its built-in map type. Maps in Go are versatile and allow us to manage collections of key-value pairs efficiently. This task will help you understand how to handle map operations in Go, focusing on adding, retrieving, and deleting entries. By the end of this lesson, you'll have a solid grasp of these fundamental operations and understand the practical significance of Go's map in real-world applications.

Introducing Functions to Implement

In this task, we will implement three functions to manage our address book:

  • func (ab *AddressBook) addContact(name, phoneNumber string) bool: Adds a new contact. Returns false if the contact already exists; otherwise, adds the contact and returns true. In this task, phone numbers are immutable, so overwriting an existing contact's number is not allowed.
  • func (ab *AddressBook) getContact(name string) string: Retrieves the phone number for a given name. Returns an empty string if the contact does not exist.
  • func (ab *AddressBook) deleteContact(name string) bool: Deletes a contact with the given name. Returns true if the contact exists and is deleted, false otherwise.

With these functions, we aim to illustrate a common use case for maps: managing sets of data where each entry is uniquely identified by a key, with the map efficiently handling insertions, deletions, and lookups. Let's break down each function in detail in the next sections.

Step 1: Implementing addContact

This function adds a new contact to the address book with the given name and phoneNumber. If the contact already exists, it returns false. Otherwise, it adds the contact and returns true.

Question: Why do you think we need to check if the contact already exists?

Answer: To avoid overwriting pre-existing entries. If a contact with the same name already exists, we shouldn't allow overwriting its phone number in this method, as contact names are unique identifiers within our map.

Here is the function implementation:

package main

import (
    "fmt"
)

type AddressBook struct {
    contacts map[string]string
}

func (ab *AddressBook) addContact(name, phoneNumber string) bool {
    if _, exists := ab.contacts[name]; exists {
        return false
    }
    ab.contacts[name] = phoneNumber
    return true
}

func (ab *AddressBook) printContacts() {
    for name, phoneNumber := range ab.contacts {
        fmt.Printf("%s: %s\n", name, phoneNumber)
    }
}

// Example usage:
func main() {
    addressBook := &AddressBook{contacts: make(map[string]string)}
    fmt.Println(addressBook.addContact("Alice", "123-456-7890")) // true
    fmt.Println(addressBook.addContact("Alice", "098-765-4321")) // false
    addressBook.printContacts() // Alice: 123-456-7890
}

In this function:

  • We use the comma, ok idiom (_, exists := ab.contacts[name]) to check if the contact already exists.
  • If it does exist, we return false; otherwise, we add it to our map and return true.
  • This ensures the integrity of each contact, enforcing a no-duplicate rule.
Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal