Si j'ai une carte m, y a-t-il un meilleur moyen d'obtenir une tranche des valeurs v alors
package main
import (
"fmt"
)
func main() {
m := make(map[int]string)
m[1] = "a"
m[2] = "b"
m[3] = "c"
m[4] = "d"
// Can this be done better?
v := make([]string, len(m), len(m))
idx := 0
for _, value := range m {
v[idx] = value
idx++
}
fmt.Println(v)
}
Y a-t-il une fonction intégrée d'une carte? Y a-t-il une fonction dans un package Go, ou est-ce le meilleur code à faire si je dois le faire?
_
paridx
et utilisezidx-1
lors de l'affectation des valeurs de tranche.Réponses:
Malheureusement non. Il n'y a aucun moyen intégré de faire cela.
En remarque, vous pouvez omettre l'argument de capacité lors de la création de votre tranche:
v := make([]string, len(m))
La capacité est implicitement la même que la longueur ici.
la source
En complément du message de Jimt:
Vous pouvez également utiliser
append
plutôt qu'affecter explicitement les valeurs à leurs indices:m := make(map[int]string) m[1] = "a" m[2] = "b" m[3] = "c" m[4] = "d" v := make([]string, 0, len(m)) for _, value := range m { v = append(v, value) }
Notez que la longueur est nulle (aucun élément n'est encore présent) mais la capacité (espace alloué) est initialisée avec le nombre d'éléments de
m
. Ceci est fait, ilappend
n'est donc pas nécessaire d'allouer de la mémoire chaque fois que la capacité de la tranchev
est épuisée.Vous pouvez également
make
la tranche sans la valeur de capacité et laisserappend
allouer la mémoire pour elle-même.la source
make([]appsv1.Deployment, len(d))
ajoutera à un tas d'éléments vides qui ont été créés lorsque vous avez allouélen(d)
des éléments vides.Pour autant que je sache actuellement, go n'a pas de méthode pour concaténer des chaînes / octets dans une chaîne résultante sans faire au moins / deux / copies.
Vous devez actuellement augmenter un [] octet puisque toutes les valeurs de chaîne sont const, ALORS vous devez utiliser la chaîne intégrée pour que le langage crée un objet chaîne 'béni', pour lequel il copiera le tampon car quelque chose quelque part pourrait avoir une référence à l'adresse sauvegardant l'octet [].
Si un octet [] convient alors vous pouvez gagner une très légère avance sur la fonction bytes.Join en faisant une allocation et en faisant la copie vous-même.
package main import ( "fmt" ) func main() { m := make(map[int]string) m[1] = "a" ; m[2] = "b" ; m[3] = "c" ; m[4] = "d" ip := 0 /* If the elements of m are not all of fixed length you must use a method like this; * in that case also consider: * bytes.Join() and/or * strings.Join() * They are likely preferable for maintainability over small performance change. for _, v := range m { ip += len(v) } */ ip = len(m) * 1 // length of elements in m r := make([]byte, ip, ip) ip = 0 for _, v := range m { ip += copy(r[ip:], v) } // r (return value) is currently a []byte, it mostly differs from 'string' // in that it can be grown and has a different default fmt method. fmt.Printf("%s\n", r) }
la source
Vous pouvez utiliser ce
maps
package:go get https://github.com/drgrib/maps
Alors tout ce que tu as à appeler c'est
Il est sans danger pour cette
map
combinaison courante . Vous pouvez utiliser d'generate
autres fonctions de type sécurisé pour tout autre type d'map
utilisation de l'mapper
outil dans le même package.Divulgation complète: je suis le créateur de ce package. Je l'ai créé parce que je me suis retrouvé à réécrire ces fonctions à
map
plusieurs reprises.la source
Pas nécessairement mieux, mais la façon la plus propre de le faire est de définir à la fois la LONGUEUR de la tranche et la CAPACITÉ comme
txs := make([]Tx, 0, len(txMap))
// Defines the Slice capacity to match the Map elements count txs := make([]Tx, 0, len(txMap)) for _, tx := range txMap { txs = append(txs, tx) }
Exemple complet:
package main import ( "github.com/davecgh/go-spew/spew" ) type Tx struct { from string to string value uint64 } func main() { // Extra touch pre-defining the Map length to avoid reallocation txMap := make(map[string]Tx, 3) txMap["tx1"] = Tx{"andrej", "babayaga", 10} txMap["tx2"] = Tx{"andrej", "babayaga", 20} txMap["tx3"] = Tx{"andrej", "babayaga", 30} txSlice := getTXsAsSlice(txMap) spew.Dump(txSlice) } func getTXsAsSlice(txMap map[string]Tx) []Tx { // Defines the Slice capacity to match the Map elements count txs := make([]Tx, 0, len(txMap)) for _, tx := range txMap { txs = append(txs, tx) } return txs }
Solution simple mais beaucoup de pièges. Lisez cet article de blog pour plus de détails: https://web3.coach/golang-how-to-convert-map-to-slice-three-gotchas
la source