Step 1 of 5 · Reading · ~4 min
Learn
Collections
Maps
A map stores key/value pairs and finds a value by its key in roughly constant time, however many pairs it holds. By the end of this lesson you can build one, read it without tripping over missing keys, tally occurrences with it, and print its contents in a stable order.
Creating, writing, reading
Key types must be comparable: strings, numbers, bools. Value types can be anything.
One landmine first: a map that is declared but never built is nil. var m map[string]int
reads fine and panics on the first write with assignment to entry in nil map. Build every
map with make or a literal and you will never meet it.
Reading a key that is not there
That is never an error. You get the value type's zero value: 0 for an int map, "" for a
string map, false for a bool map.
Convenient, but it hides one thing: a stored 0 and an absent key look identical. The
two-value form, called comma-ok, separates them:
Use comma-ok when absence itself means something, and the plain read when zero is a fine default.
Tallying with the zero value
Because a missing key reads as zero, you can add to a counter that does not exist yet. Counting the colors in a slice is one statement inside the loop:
Five items went in and len(tally) is 3, because three keys were used. When the values
carry no information, a map is Go's set: seen := map[string]bool{}, then seen[name] = true. A key can only be stored once, so the map's length tells you how many different
names went in, no matter how often each one was written.
Iteration has no order
Ranging over a map visits every pair exactly once, in an order Go deliberately randomizes on every run -- three runs, three orders, so nobody can write code that depends on it. When output must be stable, pull the keys out, sort them, and look each one up:
Counting how many entries satisfy some condition needs no sorting -- order cannot change a count -- but printing them does.
Common mistakes
- Reporting items instead of keys. For the line
red red reda program that says three colors is printing how many items it read, not the map's length. A map with one key has length 1 however often that key was written. - Treating every key as a one-timer. For
red red bluethe map has 2 keys, but only one of them was stored a single time. The number of keys and the number of keys whose value is 1 are different numbers, and the second one costs a pass over the values. - Assuming at least one entry exists. An empty input line yields an empty slice and an empty
map: both lengths are 0, and no loop body runs. Reaching for
words[0]to "get started" panics there withindex out of range. - Expecting keys to be case-insensitive. Keys are compared exactly, so
Goandgoare two separate entries. Lower-case the text first if you want them merged.
Your exercise
Tally the words of one input line in a map, then report two numbers: how many different
words appeared, and how many appeared exactly once. The starter already splits the line into
words and creates the empty map counts, and prints two zeros so you can see the shape.
The second number is the trap -- it is not the size of the map.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…