Description
Proposal Details
Background
The maps package currently provides iterator-based functions (Keys
and Values
)
that return iterators over a map's keys or values. While iterators are powerful
and composable, they require extra code to convert to slices, which is a common
use case.
Converting map keys or values to slices is a recurring pattern in Go code.
Currently, developers need to write boilerplate like:
keys := make([]KeyType, 0, len(myMap))
for k := range myMap {
keys = append(keys, k)
}
Proposal
Add two new functions to the maps package:
KeysSlice[M ~map[K]V, K comparable, V any](m M) []K
ValuesSlice[M ~map[K]V, K comparable, V any](m M) []V
These functions would extract map keys/values into slices, complementing the
existing iterator-based functions and providing a direct solution for the common
use case of converting map contents to slices.
Proposed Implementation
The implementation would be straightforward:
// KeysSlice returns a new slice containing the keys of m.
// The keys will be in an indeterminate order.
func KeysSlice[M ~map[K]V, K comparable, V any](m M) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}
// ValuesSlice returns a new slice containing the values of m.
// The values will be in an indeterminate order.
func ValuesSlice[M ~map[K]V, K comparable, V any](m M) []V {
r := make([]V, 0, len(m))
for _, v := range m {
r = append(r, v)
}
return r
}
Use Cases
These functions would be useful for various common scenarios:
-
Working with map keys in a sorted manner:
keys := maps.KeysSlice(myMap) slices.Sort(keys) // Process keys in sorted order
-
Getting a list of values for processing:
values := maps.ValuesSlice(userRoles) for _, role := range values { // Process roles }
-
Converting to a different representation:
// Easily convert map values to a slice for API responses response.Items = maps.ValuesSlice(dataMap)
Alternatives Considered
-
Using existing iterator functions:
WhileKeys()
andValues()
combined withslices.Collect()
can achieve
similar functionality, this requires importing multiple packages and is less
discoverable for users:keys := slices.Collect(maps.Keys(myMap))
-
Using range with assignment:
The current approach of manually creating slices and iterating is verbose and
requires boilerplate code.
Compatibility
This change adds new functionality without modifying existing behavior, so it has
no compatibility concerns.
/cc @golang/maps-owners