Go Maps in Depth
A grouped map is a map whose values hold more values. A map of slices keeps a whole list under one key.
A map of slices groups names by first letter
Each name joins the slice stored at its first letter. The report walks the sorted keys, so the groups print in letter order.
package main
import (
"fmt"
"slices"
)
func main() {
groups := map[string][]string{}
names := []string{"Ana", "Al", "Bo", "Bea", "Cy"}
for _, name := range names {
key := name[:1]
groups[key] = append(groups[key], name)
}
keys := []string{}
for k := range groups {
keys = append(keys, k)
}
slices.Sort(keys)
for _, k := range keys {
fmt.Println(k, groups[k])
}
}A nested map reads a deep value
The outer key names a person, and the inner key names a subject. Two bracket reads in a row reach the score.
package main
import "fmt"
func main() {
scores := map[string]map[string]int{
"Ana": {"math": 90, "art": 75},
"Bo": {"math": 82, "art": 88},
}
fmt.Println(scores["Ana"]["math"])
fmt.Println(scores["Bo"]["art"])
}Counting with a sorted report
Each word adds one to its count in the map. Two words tie at two, and the sorted keys place ant before bee.
package main
import (
"fmt"
"slices"
)
func main() {
counts := map[string]int{}
words := []string{"ant", "bee", "ant", "cat", "bee", "dog"}
for _, w := range words {
counts[w]++
}
keys := []string{}
for k := range counts {
keys = append(keys, k)
}
slices.Sort(keys)
for _, k := range keys {
fmt.Println(k, counts[k])
}
}A struct value from a map is a copy
The Stock value comes out of the map into a variable. Changing the copy leaves the stored count at 5 until the copy is assigned back.
package main
import "fmt"
type Stock struct {
Item string
Count int
}
func main() {
shelf := map[string]Stock{"pen": {"Pen", 5}}
s := shelf["pen"]
s.Count = 9
fmt.Println(shelf["pen"].Count)
shelf["pen"] = s
fmt.Println(shelf["pen"].Count)
}Example
package main
import (
"fmt"
"slices"
)
func main() {
groups := map[int][]string{}
words := []string{"cat", "tree", "dog", "fish", "sun", "bird"}
for _, w := range words {
groups[len(w)] = append(groups[len(w)], w)
}
keys := []int{}
for k := range groups {
keys = append(keys, k)
}
slices.Sort(keys)
for _, k := range keys {
fmt.Println(k, groups[k])
}
}Key points
- A map of slices stores one slice under each key.
- Appending to the slice at a key grows that group in place.
- A nested map is a map whose values are maps.
- A deep read follows one key into the inner map, then a second key into its value.
- A struct value read from a map is a copy of the stored value.
- A changed copy is stored only when the program assigns it back to the key.
- Sorting the keys before printing gives a report in a fixed order.
In this example, each word joins the group stored at its length. The words cat, dog and sun land under the key 3. The words tree, fish and bird land under the key 4. The keys are sorted before the loop prints, so the report starts with the shorter words.
Note
Two counts can tie, and the sorted key order decides which tied line prints first.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Go Playground
Exercise
A program changes a struct value it read from a map, but the map shows the old value. What step is missing?