๐ŸŽ“ A1Learner
๐Ÿ”
0 of 34 lessons completed

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?