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]intdeclares a map but doesn't create one;m["a"] = 1then panics withassignment to entry in nil map. Create it withmakeor a literal first. (Reading from a nil map is fine.) - Relying on
rangeorder — 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]
}