web-dev-qa-db-fra.com

Obtenir une tranche de clés d'une carte

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++
}
151
Saswat Padhi

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.

149
peterSO

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.

277
Vinay Pai

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]
}
54
Denis Kreshikhin

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.

8
rightfold

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)
}
1
Lalit Sharma

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 appending, 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.)

0
Nico Villanueva