Iterowanie po wszystkich klawiszach mapy

316

Czy istnieje sposób na uzyskanie listy wszystkich kluczy na mapie językowej Go? Liczba elementów jest podana przez len(), ale jeśli mam mapę, taką jak:

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

Jak iterować po wszystkich kluczach?

Martin Redmond
źródło

Odpowiedzi:

546

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

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

lub

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

Specyfikacje języka Go dla forinstrukcji określa, że ​​pierwsza wartość jest kluczem, druga zmienna jest wartością, ale nie musi być obecna.

Jonathan Feinberg
źródło
22
Jako możliwe gotcha, zauważ, że kolejność iteracji jest niezdefiniowana. groups.google.com/d/msg/golang-nuts/YfDxpkI34hY/4pktJI2ytusJ
mna
23
Sudhir: specyfikacja języka golang wyraźnie definiuje mapy jako posiadające nieokreśloną kolejność kluczy. Ponadto, odkąd Go 1, kolejność kluczy jest celowo losowo wybierana między seriami, aby zapobiec zależności od jakiejkolwiek postrzeganej kolejności.
Mark Renouf
6
Zauważ, że nie jest to zmienna iteracja, co oznacza, że ​​usunięcie klucza będzie wymagało ponownego uruchomienia iteracji.
Rick Smith
Również w przypadku małych zestawów danych kolejność map może być przewidywalna.
woot
14

Oto prosty sposób na zdobycie sliceklawiszy mapy.

// 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]
}
a8m
źródło
Czy Keysfunkcja może pobrać mapę z kluczami dowolnego typu, a nie tylko z ciągami znaków?
Robert T. McGibbon,
func Keys(m map[interface{}]interface{}) (keys []interface{}), @ RobertT.McGibbon musisz zmienić funkcję „prototyp”
a8m
1
@ArielM. To działałoby tylko w przypadku konkretnego typu map[interface{}]interface{}. Go nie obsługuje rodzajów ogólnych. Nie można utworzyć funkcji z mapparametrem, który akceptuje mapy z różnymi typami kluczy.
icza
10

Czy istnieje sposób na uzyskanie listy wszystkich kluczy na mapie językowej Go?

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

jak iterować po wszystkich kluczach?

Użyj zaakceptowanej odpowiedzi:

for k, _ := range m { ... }
Sridhar
źródło
1
Myślę, że miałeś na myśli for _, k := range v.MapKeys(), ponieważ w twoim przykładzie kbędzie to int indeks części klucza
Brian Leishman