C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
A bird is blue. We can map the string "bird" to the string "blue." This improves performance and enforces uniqueness of keys.
A solution. The map built-in provides a way to declare, with composite literal syntax, an entire table. And with a simple access we can find a value from a key (or test if a value exists).
First example. We first create a map that has string keys and string values. The key type is specified in the brackets after the "map" keyword. The value type comes afterward.
Syntax: We show the composite literal syntax in the "colors" table. We map the string "cat" to "black."
Access: We retrieve a value from the map at the key "snake." The string "green" is returned.
Based on:
Golang 1.4
Golang program that uses map
package main
import "fmt"
func main() {
// Map animal names to color strings.
// ... Create a map with composite literal syntax.
colors := map[string]string{
"bird": "blue",
"snake": "green",
"cat": "black",
}
// Get color of snake.
c := colors["snake"]
// Display string.
fmt.Println(c)
}
Output
green

Add with assignment. An empty map can be created. We can then add keys and associated values imperatively (with statements) in separate lines.
Tip: In this way we can add data to a map in a loop. We must specify an empty initialization of the map.
Len: The len operator, also used on arrays and slices, can be used on a map. It counts keys (which is the same as the count of values).
Golang program that adds keys with assignments
package main
import "fmt"
func main() {
// Create an empty map.
names := map[int]string{}
// Add three pairs to the map in separate statements.
names[990] = "file.txt"
names[1009] = "data.xls"
names[1209] = "image.jpg"
// There are three pairs in the map.
fmt.Println(len(names))
}
Output
3

Delete. We can add keys to a map by assigning them. But to delete a key and its value, we must use the delete built-in: the pair is entirely erased.
Here: We add three entries to a map. The length is 3. We then delete one key and the length is reduced to 2.
Golang program that uses delete built-in
package main
import "fmt"
func main() {
// Create an empty map and add three pairs to it.
ids := map[string]int{}
ids["steve"] = 10
ids["mark"] = 20
ids["adnan"] = 30
fmt.Println(len(ids))
// Delete one key from it.
delete(ids, "steve")
fmt.Println(len(ids))
}
Output
3
2

Loop over map. With the "for" and "range" keywords we can iterate over a map. We must assign variables to the two return values returned by the range expression.
Note: We can use a blank identifier (the underscore "_") to store the result of a key or value if it will not be used.
Golang program that uses for-loop on map
package main
import "fmt"
func main() {
// Create a string to string map.
animals := map[string]string{}
animals["cat"] = "Mittens"
animals["dog"] = "Spot"
// Loop over the map.
for key, value := range animals {
fmt.Println(key, "=", value)
}
}
Output
cat = Mittens
dog = Spot

Ok syntax. A key lookup in a map returns two values: the value (if found) and a value that indicates success or failure. We often name this "success" value "ok."
Ok: In the if-statements, the ok variable is set and then tested. If true, the inner blocks are reached.
Tip: With the "comma ok" idiom, we can test for existence and store the lookup result in one statement.
Golang program that uses map, ok syntax
package main
import (
"fmt"
)
func main() {
meds := map[string]int{
"Ativan": 15,
"Xanax": 20,
"Klonopin": 30,
}
// The ok variable is set to true.
if dosage, ok := meds["Xanax"]; ok {
fmt.Println("Xanax", dosage)
}
// The ok variable is set to false.
// ... The string does not exist in the map.
if dosage, ok := meds["Atenolol"]; ok {
fmt.Println("Atenolol", dosage)
}
}
Output
Xanax 20

Performance, map versus slice. A map accelerates lookups: it uses a special hash code to guide a search. Here I compare a map search to a slice search.
And: For both the map and the slice, we try to locate the index of the value "bird." The map has indexes as its values.
Result: The map has a clear performance advantage in this case. For larger amounts of data, this will become even greater.
Golang program that benchmarks map, slice
package main
import (
"fmt"
"time"
)
func main() {
lookup := map[string]int{
"cat": 0,
"dog": 1,
"fish": 2,
"bird": 3}
values := []string{"cat", "dog", "fish", "bird"}
temp := 0
t0 := time.Now()
// Version 1: search map with lookup.
for i := 0; i < 10000000; i++ {
v, ok := lookup["bird"]
if ok {
temp = v
}
}
t1 := time.Now()
// Version 2: search slice with for-loop.
for i := 0; i < 10000000; i++ {
for x := range(values) {
if values[x] == "bird" {
temp = x
break
}
}
}
t2 := time.Now()
// Benchmark results.
fmt.Println(temp)
fmt.Println(t1.Sub(t0))
fmt.Println(t2.Sub(t1))
}
Results
3
176.1265ms map lookup
212.1489ms slice, for-loop
A summary. We used the map built-in to link keys to values. We tested that keys exist and we retrieved the appropriate values. A map provides a clear performance win.