ChatGPT解决这个技术问题 Extra ChatGPT

Iterating over all the keys of a map

Is there a way to get a list of all the keys in a Go language map? The number of elements is given by len(), but if I have a map like:

m := map[string]string{ "key1":"val1", "key2":"val2" };

How do I iterate over all the keys?


D
Dougnukem

https://play.golang.org/p/JGZ7mN0-U-

for k, v := range m { 
    fmt.Printf("key[%s] value[%s]\n", k, v)
}

or

for k := range m {
    fmt.Printf("key[%s] value[%s]\n", k, m[k])
}

Go language specs for for statements specifies that the first value is the key, the second variable is the value, but doesn't have to be present.


As a possible gotcha, note that the order of the iteration is undefined. groups.google.com/d/msg/golang-nuts/YfDxpkI34hY/4pktJI2ytusJ
Sudhir: golang language spec explicitly defines maps as having undefined ordering of keys. Furthermore, since Go 1, key order is intentionally randomized between runs to prevent dependency on any perceived order.
Note that this is not a mutable iteration, which is to say deleting a key will require you to restart the iteration.
Also for small data sets, map order could be predictable.
a
a8m

Here's some easy way to get slice of the map-keys.

// Return keys of the given map
func Keys(m map[string]interface{}) (keys []string) {
    for k := range m {
        keys = append(keys, k)
    }
    return keys
}

// use `Keys` func
func main() {
    m := map[string]interface{}{
        "foo": 1,
        "bar": true,
        "baz": "baz",
    }
    fmt.Println(Keys(m)) // [foo bar baz]
}

Is it possible for the Keys function to take a map with keys of any type, not just strings?
func Keys(m map[interface{}]interface{}) (keys []interface{}), @RobertT.McGibbon you need to change the function "prototype"
@ArielM. That would only work for the exact type map[interface{}]interface{}. Go does not support generics. You can't create a function with a map parameter which accepts maps with different key types.
S
Sridhar

Is there a way to get a list of all the keys in a Go language map?

ks := reflect.ValueOf(m).MapKeys()

how do I iterate over all the keys?

Use the accepted answer:

for _, k := range m { ... }

I think you meant for _, k := range v.MapKeys(), since in your example, k would be the int index of the slice of keys
M
Mohsen

A Type agnostic solution:

for _, key := range reflect.ValueOf(yourMap).MapKeys() {
    value := yourMap.MapIndex(key).Interface()
    fmt.Println("Key:", key, "Value:", value)
}  

what's s in value := s.MapIndex(key).Interface()?
@KwakuBiney Thank you for your attention. I updated the answer. I can't test it now though.
f
fliX

Using Generics:

func Keys[K comparable, V any](m map[K]V) []K {
    keys := make([]K, 0, len(m))

    for k := range m {
        keys = append(keys, k)
    }

    return keys
}