Walk a sequence and count occurrences of each value in a map. Classic "get current count, add one, write back" loop.

Algorithm

Basic Implementation

basic.go
package main

import "fmt"

func main() {
	words := []string{"fig", "apple", "fig", "pear", "apple", "fig"}
	counts := map[string]int{}
	order := []string{}
	for i := 0; i < len(words); i++ {
		word := words[i]
		_, seen := counts[word]
		if !seen {
			order = append(order, word)
			counts[word] = 1
		} else {
			counts[word] = counts[word] + 1
		}
	}
	fmt.Print("{")
	for i, key := range order {
		if i > 0 {
			fmt.Print(", ")
		}
		fmt.Printf("%s: %d", key, counts[key])
	}
	fmt.Println("}")
}

The pinned input is [fig, apple, fig, pear, apple, fig]. The diagrams show get-or-default, writeback, and final bucket contents.

Step 1 - First write creates a key

fig is absent, so get-or-default reads 0 and writes fig: 1.

After reading the first word fig.wordold countnew countmapfig01{fig: 1}

Step 2 - Existing keys increment

The second fig reads 1 and writes 2; apple has its own count.

After fig, apple, fig.scanfigapplepearafter fig100after apple110after fig210

Step 3 - Final counts

The full scan produces fig: 3, apple: 2, and pear: 1.

Final map for [fig, apple, fig, pear, apple, fig].bucket/keycountfig3apple2pear1

Complexity

  • Time: O(n) average with map[string]int.
  • Space: O(k) where k is the number of distinct keys.

Implementation notes

  • Go: counts := map[string]int{} is the idiomatic map literal, and the _, seen := counts[word] comma-ok pattern is the canonical "did I see this key" test in Go.
  • The auxiliary order slice preserves first-seen order so the final printout is deterministic — Go's map iteration order is intentionally randomised.
  • The replay renders the map as a list of key/value rows in first-seen order and animates the count increment on each frame.
get-or-default A first-time `word` triggers the "default" branch: append to `order` and set `counts[word] = 1`. A repeat read-modify-writes `counts[word] + 1`.
first-seen order Keys are tracked in `order` (a `[]string`) to keep the printout deterministic; Go's `map` iteration order is randomised by design.