The golang.org/x/exp/maps package defines various utility functions useful for working with maps of any type. It provides generic functions for common map operations including cloning, copying, comparison, key/value extraction, and conditional deletion.
golang.org/x/exp/mapsimport "golang.org/x/exp/maps"package main
import (
"fmt"
"golang.org/x/exp/maps"
)
func main() {
// Create a map
m := map[string]int{"a": 1, "b": 2, "c": 3}
// Extract keys and values
keys := maps.Keys(m)
values := maps.Values(m)
fmt.Println("Keys:", keys)
fmt.Println("Values:", values)
// Clone a map
cloned := maps.Clone(m)
fmt.Println("Cloned:", cloned)
// Compare two maps
m2 := map[string]int{"a": 1, "b": 2, "c": 3}
equal := maps.Equal(m, m2)
fmt.Println("Equal:", equal)
// Delete entries matching a condition
maps.DeleteFunc(m, func(k string, v int) bool {
return v > 1
})
fmt.Println("After DeleteFunc:", m)
}Extracts all keys from a map and returns them as a slice. The keys are returned in an indeterminate order.
func Keys[M ~map[K]V, K comparable, V any](m M) []KParameters:
m: The map to extract keys fromReturns:
Example:
m := map[string]int{"apple": 1, "banana": 2, "cherry": 3}
keys := maps.Keys(m)
// keys contains ["apple", "banana", "cherry"] in some orderExtracts all values from a map and returns them as a slice. The values are returned in an indeterminate order.
func Values[M ~map[K]V, K comparable, V any](m M) []VParameters:
m: The map to extract values fromReturns:
Example:
m := map[string]int{"apple": 1, "banana": 2, "cherry": 3}
values := maps.Values(m)
// values contains [1, 2, 3] in some orderCreates a shallow copy of a map. New keys and values are set using ordinary assignment, so referenced types (pointers, slices, etc.) are not deeply cloned.
func Clone[M ~map[K]V, K comparable, V any](m M) MParameters:
m: The map to cloneReturns:
Example:
original := map[string]string{"name": "Alice", "city": "NYC"}
cloned := maps.Clone(original)
cloned["name"] = "Bob"
// original["name"] is still "Alice" (independent copy)Copies all key/value pairs from a source map into a destination map. If a key exists in both maps, the value in the destination is overwritten with the value from the source.
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2)Parameters:
dst: The destination map (modified in place)src: The source map to copy fromExample:
dst := map[string]int{"a": 1, "b": 2}
src := map[string]int{"b": 20, "c": 3}
maps.Copy(dst, src)
// dst is now {"a": 1, "b": 20, "c": 3}Removes all entries from a map, leaving it empty. This modifies the map in place.
func Clear[M ~map[K]V, K comparable, V any](m M)Parameters:
m: The map to clearExample:
m := map[string]int{"a": 1, "b": 2, "c": 3}
maps.Clear(m)
// m is now empty: map[]Compares two maps for equality. Returns true if both maps contain identical key/value pairs. Values are compared using the == operator.
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) boolParameters:
m1: The first map to comparem2: The second map to compareReturns:
true if both maps have the same key/value pairs, false otherwiseExample:
m1 := map[string]int{"a": 1, "b": 2}
m2 := map[string]int{"a": 1, "b": 2}
m3 := map[string]int{"a": 1, "b": 3}
equal1 := maps.Equal(m1, m2) // true
equal2 := maps.Equal(m1, m3) // falseCompares two maps for equality using a custom comparison function for values. Keys are still compared using the == operator. This is useful when direct equality comparison is not appropriate for the values.
func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) boolParameters:
m1: The first map to comparem2: The second map to compareeq: A comparison function that returns true if two values are considered equalReturns:
true if both maps have the same keys and their values are considered equal by the eq function, false otherwiseExample:
type Person struct {
Name string
Age int
}
m1 := map[string]Person{"alice": {Name: "Alice", Age: 30}}
m2 := map[string]Person{"alice": {Name: "Alice", Age: 30}}
// Compare only the Name field, ignoring Age
equal := maps.EqualFunc(m1, m2, func(p1, p2 Person) bool {
return p1.Name == p2.Name
})
// equal is trueDeletes any key/value pairs from a map for which the provided deletion function returns true. This modifies the map in place.
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool)Parameters:
m: The map to modifydel: A function that takes a key and value, and returns true if the entry should be deleted, false otherwiseExample:
m := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4}
// Delete all entries with values greater than 2
maps.DeleteFunc(m, func(k string, v int) bool {
return v > 2
})
// m is now {"a": 1, "b": 2}The package uses Go's generic type constraints:
K comparable // Keys must be comparable using ==
V any // Values can be any type
M ~map[K]V // M is a type constraint that allows any map type with keys K and values VAll generic functions in this package support:
== operatorWhile the keys slice returned by Keys() has indeterminate order, you can sort it if needed:
import (
"golang.org/x/exp/maps"
"sort"
)
m := map[string]int{"c": 3, "a": 1, "b": 2}
keys := maps.Keys(m)
sort.Strings(keys)
// keys is now ["a", "b", "c"]m1 := map[string]int{"a": 1, "b": 2}
m2 := map[string]int{"c": 3, "d": 4}
m3 := map[string]int{"e": 5}
result := maps.Clone(m1)
maps.Copy(result, m2)
maps.Copy(result, m3)
// result contains all entries from m1, m2, and m3m := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4}
// Create a filtered copy
filtered := maps.Clone(m)
maps.DeleteFunc(filtered, func(k string, v int) bool {
return v < 2 || v > 3
})
// filtered now contains only {"b": 2, "c": 3}m1 := map[string][]int{"a": {1, 2}, "b": {3, 4}}
m2 := map[string][]int{"a": {1, 2}, "b": {3, 4}}
// Compare slices element by element
equal := maps.EqualFunc(m1, m2, func(v1, v2 []int) bool {
if len(v1) != len(v2) {
return false
}
for i := range v1 {
if v1[i] != v2[i] {
return false
}
}
return true
})
// equal is trueAll functions in this package use generic type parameters to work with any map type:
[M ~map[K]V, K comparable, V any] - Allows the function to work with any map type where K is comparable and V is any type[M1, M2 ~map[K]V, K, V comparable] - For functions comparing two maps, both must have the same key/value types[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any] - For functions comparing maps that may have different value typesKeys() and Values() return entries in an indeterminate order.Clone() function creates a shallow copy. Referenced types (slices, pointers, etc.) are copied by reference, not by value.Keys(nil) returns an empty slice.