Skip to content

Maps

Maps are essentially Go's equivalent to a dictionary in say, Python. Instead of having a zero based index, maps enable us to have our own index key type, defining key values pairs.

Maps are not ordered.

Maps are dynamic sized like slices.

Map:

KEY:    "foo"   "oof"
VALUE:  "bar"   "rab"

Initialize map

Decare an empty map:

main.go
package main

import (
    "fmt"
)

func main() {
    var myMap map[string]int
    fmt.Println(myMap)
}

Populating map

You can define the initial values for a new map using the following syntax:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    fmt.Println(myMap)
}

Accessing map

You can access a specific key value:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    fmt.Println(myMap["foo"])
}

Modify key value

You can update a key value pair, for example:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    fmt.Println(myMap["foo"])

    myMap["bar"] = 42

    fmt.Println(myMap["bar"])
}

Results in:

1
42

Length of map

To determine the length of an map:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    fmt.Println(len(myMap))
}

Copy map

Maps are also reference type just like slices, so changing the value in one map copied from another means the values is reflected in both maps.

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    anotherMap := myMap
    anotherMap["bar"] = 42
    fmt.Println(myMap)
    fmt.Println(anotherMap)
}

Output:

map[bar:42 foo:1]
map[bar:42 foo:1]

If you do want to create an independent clone, there is a function to do that, import the maps package:

main.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    anotherMap := maps.Clone(myMap)

    myMap["foo"] = 10
    anotherMap["bar"] = 42

    fmt.Println(myMap)
    fmt.Println(anotherMap)
}

Append to map

You can add new key/value pairs to a map:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    myMap["doh"] = 99
    fmt.Println(myMap)
}

Delete from map

You can remove a key/value pair:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    delete(myMap, "foo")
    fmt.Println(myMap)
}

If you query this map for foo again, you will get 0, but where does that value come from? We know foo was deleted, but if you need to explitley know it 0 can from the map or not you can include a test.

For example the following will output 0 false:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string]int{"foo": 1, "bar": 2}
    delete(myMap, "foo")
    v, ok := myMap["foo"]
    fmt.Println(v, ok)
}

Remove the line delete(myMap, "foo") and the result would be 1 true confirming that the value 1 did indeed come from the map myMap.

Nested maps

Heres and example of a key which contains multiple values:

main.go
package main

import (
    "fmt"
)

func main() {
    myMap := map[string][]string{
        "animals": {"dog", "cat", "rabbit", "duck", "mouse"},
    }

    fmt.Println(myMap["animals"])
    fmt.Println(myMap["animals"][0])

}

Output:

[dog cat rabbit duck mouse]
dog