it-swarm.com.de

Einen Schlüssel aus einer Karte holen

Gibt es eine einfachere/nettere Methode, um ein Stück von einer Karte in Go abzurufen?

Momentan durchlaufe ich die Karte und kopiere die Schlüssel in ein Slice:

i := 0
keys := make([]int, len(mymap))
for k := range mymap {
    keys[i] = k
    i++
}
151
Saswat Padhi

Zum Beispiel,

package main

func main() {
    mymap := make(map[int]string)
    keys := make([]int, 0, len(mymap))
    for k := range mymap {
        keys = append(keys, k)
    }
}

Um in Go effizient zu sein, ist es wichtig, die Speicherzuordnung zu minimieren.

149
peterSO

Dies ist eine alte Frage, aber hier sind meine zwei Cents. Die Antwort von PeterSO ist etwas prägnanter, aber etwas weniger effizient. Sie wissen bereits, wie groß es sein wird, so dass Sie nicht einmal append verwenden müssen:

keys := make([]int, len(mymap))

i := 0
for k := range mymap {
    keys[i] = k
    i++
}

In den meisten Situationen macht es wahrscheinlich keinen großen Unterschied, aber es ist nicht viel mehr Arbeit, und in meinen Tests (mit einer Map mit 1.000.000 zufälligen int64-Schlüsseln und dann zehnmal mit jeder Methode ein Array von Schlüsseln generieren) Es ist etwa 20% schneller, Mitglieder des Arrays direkt zuzuweisen, als Append zu verwenden.

Obwohl durch das Festlegen der Kapazität keine Neuzuordnungen mehr erforderlich ist, muss append noch zusätzliche Arbeit ausführen, um zu überprüfen, ob die Kapazität bei jedem anfügen erreicht ist.

277
Vinay Pai

Sie können auch ein Array von Schlüsseln mit dem Typ []Value über die Methode MapKeys von struct Value aus dem Paket "reflect" verwenden:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    abc := map[string]int{
        "a": 1,
        "b": 2,
        "c": 3,
    }

    keys := reflect.ValueOf(abc).MapKeys()

    fmt.Println(keys) // [a b c]
}
54

Eine schönere Methode wäre, append zu verwenden:

keys = []int{}
for k := range mymap {
    keys = append(keys, k)
}

Abgesehen davon haben Sie kein Glück - Go ist keine sehr ausdrucksstarke Sprache.

8
rightfold

Besuchen Sie https://play.golang.org/p/dx6PTtuBXQW

package main

import (
    "fmt"
    "sort"
)

func main() {
    mapEg := map[string]string{"c":"a","a":"c","b":"b"}
    keys := make([]string, 0, len(mapEg))
    for k := range mapEg {
        keys = append(keys, k)
    }
    sort.Strings(keys)
    fmt.Println(keys)
}
1
Lalit Sharma

Ich habe einen skizzenhaften Benchmark über die drei in anderen Antworten beschriebenen Methoden erstellt.

Offensichtlich ist das Zuweisen des Slice vor dem Ziehen der Tasten schneller als appending, aber überraschenderweise ist die reflect.ValueOf(m).MapKeys()-Methode wesentlich langsamer als die letztere:

❯ go run scratch.go
populating
filling 100000000 slots
done in 56.630774791s
running prealloc
took: 9.989049786s
running append
took: 18.948676741s
running reflect
took: 25.50070649s

Hier ist der Code: https://play.golang.org/p/Z8O6a2jyfTH (Wenn Sie es auf dem Spielplatz ausführen, wird abgebrochen, dass es zu lange dauert, also führen Sie es lokal aus.)

0
Nico Villanueva