Existe-t-il un moyen plus simple/plus pratique d’obtenir une part de clés d’une carte dans Go?
Actuellement, je parcours la carte et copie les clés dans une tranche:
i := 0
keys := make([]int, len(mymap))
for k := range mymap {
keys[i] = k
i++
}
Par exemple,
package main
func main() {
mymap := make(map[int]string)
keys := make([]int, 0, len(mymap))
for k := range mymap {
keys = append(keys, k)
}
}
Pour être efficace dans Go, il est important de minimiser les allocations de mémoire.
C'est une vieille question, mais voici mes deux cents. La réponse de PeterSO est légèrement plus concise, mais légèrement moins efficace. Vous savez déjà quelle sera sa taille, vous n'aurez même pas besoin d'utiliser append:
keys := make([]int, len(mymap))
i := 0
for k := range mymap {
keys[i] = k
i++
}
Dans la plupart des situations, cela ne fera probablement pas une grande différence, mais cela ne demandera pas beaucoup plus de travail, et dans mes tests (utiliser une carte avec 1 000 000 clés int64
aléatoires et générer ensuite le tableau de clés dix fois avec chaque méthode), environ 20% plus rapide d’affecter directement les membres du tableau que d’utiliser append.
Bien que la définition de la capacité élimine les réaffectations, append doit néanmoins effectuer un travail supplémentaire pour vérifier si vous avez atteint la capacité maximale.
Vous pouvez aussi prendre un tableau de clés avec le type []Value
par la méthode MapKeys
de struct Value
du paquet "reflect":
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]
}
Une façon plus agréable de faire ceci serait d'utiliser append
:
keys = []int{}
for k := range mymap {
keys = append(keys, k)
}
À part cela, vous n’avez pas de chance: Go n’est pas un langage très expressif.
Visitez 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)
}
J'ai fait un repère sommaire sur les trois méthodes décrites dans d'autres réponses.
Évidemment, pré-allouer la tranche avant de tirer les clés est plus rapide que append
ing, mais étonnamment, la méthode reflect.ValueOf(m).MapKeys()
est nettement plus lente que celle-ci:
❯ 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
Voici le code: https://play.golang.org/p/Z8O6a2jyfTH (L'exécuter dans la cour de récréation avorte en prétendant que cela prend trop de temps, alors, exécutez-le localement.)