Skip to content
AgileLogics
6 min read

Maps

Prerequisites: Slices

A map stores key–value pairs, like a dictionary in Python or an object used as a lookup table in JavaScript. All keys share one type and all values share one type: map[string]int maps string keys to int values.

Syntax

ages := map[string]int{"Ada": 36, "Alan": 41} // map literal
scores := make(map[string]int)                // empty, ready to use

ages["Grace"] = 85        // add or update
age := ages["Ada"]        // read (zero value if missing)
age, ok := ages["Bob"]    // "comma ok": ok is false if missing
delete(ages, "Alan")      // remove a key
len(ages)                 // number of entries

Example

package main

import "fmt"

func main() {
    ages := map[string]int{"Ada": 36, "Alan": 41}
    ages["Grace"] = 85

    fmt.Println(ages["Ada"])
    fmt.Println(ages["Nobody"])

    age, ok := ages["Nobody"]
    fmt.Println(age, ok)

    if a, found := ages["Grace"]; found {
        fmt.Println("Grace is", a)
    }

    delete(ages, "Alan")
    fmt.Println(len(ages))
    fmt.Println(ages)
}

Expected output

36
0
0 false
Grace is 85
2
map[Ada:36 Grace:85]

Reading a missing key doesn't fail — it returns the zero value (0 here). Use the comma-ok form when you need to tell "the value is 0" apart from "the key isn't there".

Iteration order is random

for name, age := range ages {
    fmt.Println(name, age)
}

Go deliberately randomizes the order in which range visits a map, so the lines above can come out in a different order on every run. (fmt.Println of a whole map is the exception: it sorts the keys, which is why the output above is predictable.) If you need a stable order, collect the keys into a slice and sort it:

names := make([]string, 0, len(ages))
for name := range ages {
    names = append(names, name)
}
sort.Strings(names) // import "sort"
for _, name := range names {
    fmt.Println(name, ages[name])
}

Common mistakes

  • Writing to a nil map. var m map[string]int declares a map but doesn't create one; m["a"] = 1 then panics with assignment to entry in nil map. Create it with make or a literal first. (Reading from a nil map is fine.)
  • Relying on range order — it is not insertion order and not sorted.
  • Using the plain v := m[key] form when a missing key and a zero value mean different things.

Practice

Count how many times each word appears in "the cat and the hat". Use strings.Fields to split the text into words, print the count for "the", then print the whole map.

Show solution
package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "the cat and the hat"
    counts := make(map[string]int)

    for _, word := range strings.Fields(text) {
        counts[word]++
    }

    fmt.Println(counts["the"]) // 2
    fmt.Println(counts)        // map[and:1 cat:1 hat:1 the:2]
}