01 Aug 2022

go

Check if a map contains a key in Go and more

Author

Gurleen Sethi

Check if a map contains a key in Go and more

The solution #

To check if a key exists in a map use the "comma ok" pattern, value, ok := yourMap[key]. When getting a value from a map Go can return a second value which is a bool denoting if the key exists inside the map for not.

Here is an example.

package main

import "fmt"

func main() {
	myMap := map[string]string{
		"key":   "value",
		"hello": "world",
	}

	value, ok := myMap["dog"]
    
	fmt.Println(ok) // prints 'false'
	fmt.Println(value) // prints '' (empty string)
}
main.go

You are fetching the value for key dog in the map which doesn't exists. The value of ok will tell you if the key exists inside the map.

nil Map

This also works in case the map is nil.

package main

import "fmt"

func main() {
	var myMap map[string]string // map is `nil`

	fmt.Println(myMap == nil) // Prints 'true'

	value, ok := myMap["dog"]
    
	fmt.Println(ok) // prints 'false'
	fmt.Println(value) // prints '' (empty string)
}
main.go

Below are some more interesting facts about maps in Go that you may or may not know.


Passing maps into functions #

When you are passing a map to a function you are not passing a copy of the map, you are passing a copy of the pointer that points to the map, so essetially the function would have access to the same map. Any changes made to the map by the function will reflect in the caller.

package main

import "fmt"

func main() {
	myMap := map[string]string{
		"key": "value",
	}

	fmt.Println(myMap) // Prints 'map[key:value]'

	DoWork(myMap)

	fmt.Println(myMap) // Prints 'map[dog:cat key:value]'
}

func DoWork(m map[string]string) {
	m["dog"] = "cat"
}
main.go

The DoWork function ends up adding a new entry(dog: cat) to the myMap.

Implementing a set using a map #

Go doesn't have a set type, but not to worry as implementing a set using a map is very easy. We need a map[T]bool type of map where T is the type of set you looking for.

A set mainly has 3 functions Add (to add values to set), Contains (check if value existins in set) and Remove (remove a value from a set).

Let's design a new type in Go called StringSet.

type StringSet struct {
	m map[string]bool // underlying map holding set values
}

func NewStringSet() StringSet {
	return StringSet{
		m: make(map[string]bool),
	}
}

func (s StringSet) Add(value string) {
	s.m[value] = true
}

func (s StringSet) Contains(value string) bool {
	return s.m[value]
}

func (s StringSet) Remove(value string) {
	delete(s.m, value)
}

Using the above StringSet.

package main

import "fmt"

func main() {
	set := NewStringSet()

	set.Add("1")
	set.Add("2")

	fmt.Println(set.Contains("1")) // Prints 'true'
	fmt.Println(set.Contains("3")) // Prints 'false'

	set.Remove("1")

	fmt.Println(set.Contains("1")) // Prints 'false'
}

Keys allowed in a map #

Go only allows types to be used as keys that are comparable. These comparable types include bool, int, string, array (not slices), interface, struct.

Some types that cannot be used as keys of a map include slice, functions, map. If you try to use these types as keys of map as below:

package main

import "fmt"

func main() {
	myMap := make(map[[]int]string) // ❌ will not compile
	fmt.Println(myMap)
}

you will get the compile error ./main.go:6:20: invalid map key type []int.

Thank you for reading this article 🙏🏻 hope you learned something new.

Email Newsletter Icon
Don't miss new articles
Get notified once/twice per month when new articles are published.
Table of Contents
TheDeveloperCafe