How to clear a map in Go?

Go

Go Problem Overview


I'm looking for something like the c++ function .clear() for the primitive type map.

Or should I just create a new map instead?

Update: Thank you for your answers. By looking at the answers I just realized that sometimes creating a new map may lead to some inconsistency that we don't want. Consider the following example:

var a map[string]string
var b map[string]string

func main() {
	a = make(map[string]string)
	b=a
	a["hello"]="world"
	a = nil
	fmt.Println(b["hello"])
}

I mean, this is still different from the .clear() function in c++, which will clear the content in the object.

Go Solutions


Solution 1 - Go

You should probably just create a new map. There's no real reason to bother trying to clear an existing one, unless the same map is being referred to by multiple pieces of code and one piece explicitly needs to clear out the values such that this change is visible to the other pieces of code.

So yeah, you should probably just say

mymap = make(map[keytype]valtype)

If you do really need to clear the existing map for whatever reason, this is simple enough:

for k := range m {
    delete(m, k)
}

Solution 2 - Go

Unlike C++, Go is a garbage collected language. You need to think things a bit differently.

When you make a new map

a := map[string]string{"hello": "world"}
a = make(map[string]string)

the original map will be garbage-collected eventually; you don't need to clear it manually. But remember that maps (and slices) are reference types; you create them with make(). The underlying map will be garbage-collected only when there are no references to it. Thus, when you do

a := map[string]string{"hello": "world"}
b := a
a = make(map[string]string)

the original array will not be garbage collected (until b is garbage-collected or b refers to something else).

Solution 3 - Go

// Method - I , say book is name of map
for k := range book {
	delete(book, k)
}

// Method - II
book = make(map[string]int)

// Method - III
book = map[string]int{}

Solution 4 - Go

The Go issue for the generic maps package (https://github.com/golang/go/issues/47649) provides maps.Clear.

The package is found in golang.org/x/exp/maps (experimental, not covered by the compatibility guarantee)

// Clear removes all entries from m, leaving it empty.
func Clear[M ~map[K]V, K comparable, V any](m M)

Its usage

func main() {
	testMap := map[string]int{"gopher": 1, "badger": 2}
	maps.Clear(testMap)
	fmt.Println(testMap)
	
	testMap["zebra"] = 2000
	fmt.Println(testMap)
}

Run the code here https://go.dev/play/p/qIdnGrd0CYs?v=gotip

Solution 5 - Go

If you are trying to do this in a loop, you can take advantage of the initialization to clear out the map for you. For example:

for i:=0; i<2; i++ {
    animalNames := make(map[string]string)
    switch i {
        case 0:
            animalNames["cat"] = "Patches"
        case 1:
            animalNames["dog"] = "Spot";
    }

    fmt.Println("For map instance", i)
    for key, value := range animalNames {
        fmt.Println(key, value)
    }
    fmt.Println("-----------\n")
}

When you execute this, it clears out the previous map and starts with an empty map. This is verified by the output:

$ go run maptests.go 
For map instance 0
cat Patches
-----------

For map instance 1
dog Spot
-----------

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlavinView Question on Stackoverflow
Solution 1 - GoLily BallardView Answer on Stackoverflow
Solution 2 - GoJohn SmithView Answer on Stackoverflow
Solution 3 - GoSumerView Answer on Stackoverflow
Solution 4 - GoMarco JärvinenView Answer on Stackoverflow
Solution 5 - GoleemicView Answer on Stackoverflow