Durchlaufen aller Schlüssel einer Karte

316

Gibt es eine Möglichkeit, eine Liste aller Schlüssel in einer Go-Sprachkarte abzurufen? Die Anzahl der Elemente ist gegeben durch len(), aber wenn ich eine Karte habe wie:

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

Wie iteriere ich über alle Schlüssel?

Martin Redmond
quelle

Antworten:

546

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

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

oder

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

Go-Sprachspezifikationen für forAnweisungen geben an, dass der erste Wert der Schlüssel ist, die zweite Variable der Wert, aber nicht vorhanden sein muss.

Jonathan Feinberg
quelle
22
Beachten Sie als mögliches Problem, dass die Reihenfolge der Iteration nicht definiert ist. groups.google.com/d/msg/golang-nuts/YfDxpkI34hY/4pktJI2ytusJ
mna
23
Sudhir: Die Golang-Sprachspezifikation definiert Karten explizit als undefiniert in der Reihenfolge der Schlüssel. Darüber hinaus wird seit Go 1 die Schlüsselreihenfolge absichtlich zwischen den Läufen randomisiert, um die Abhängigkeit von einer wahrgenommenen Reihenfolge zu verhindern.
Mark Renouf
6
Beachten Sie, dass dies keine veränderbare Iteration ist. Wenn Sie also einen Schlüssel löschen, müssen Sie die Iteration neu starten.
Rick Smith
Auch für kleine Datensätze kann die Kartenreihenfolge vorhersehbar sein.
woot
14

Hier ist ein einfacher Weg, um slicean die Kartenschlüssel zu gelangen .

// 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
quelle
Kann die KeysFunktion eine Karte mit Schlüsseln eines beliebigen Typs erstellen, nicht nur mit Zeichenfolgen?
Robert T. McGibbon
func Keys(m map[interface{}]interface{}) (keys []interface{}), @ RobertT.McGibbon müssen Sie die Funktion "Prototyp"
ändern
1
@ArielM. Das würde nur für den genauen Typ funktionieren map[interface{}]interface{}. Go unterstützt keine Generika. Sie können keine Funktion mit einem mapParameter erstellen, der Karten mit verschiedenen Schlüsseltypen akzeptiert.
icza
10

Gibt es eine Möglichkeit, eine Liste aller Schlüssel in einer Go-Sprachkarte abzurufen?

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

Wie iteriere ich über alle Schlüssel?

Verwenden Sie die akzeptierte Antwort:

for k, _ := range m { ... }
Sridhar
quelle
1
Ich denke, Sie meinten for _, k := range v.MapKeys(), da in Ihrem Beispiel kder int-Index der Schlüsselscheibe wäre
Brian Leishman