web-dev-qa-db-fra.com

Dans Golang, existe-t-il un bon moyen d’obtenir une tranche de valeurs d’une carte?

Si j'ai une carte m est-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 caractéristique construite d'une carte? Existe-t-il une fonction dans un package Go ou s'agit-il du meilleur code à effectuer si nécessaire?

61
masebase

Malheureusement non. Il n'y a pas de moyen intégré pour le faire.

En guise de remarque, vous pouvez omettre l’argument de capacité dans votre création de tranche:

v := make([]string, len(m))

La capacité est supposée être la même que la longueur ici.

44
jimt

En complément du message de jimt:

Vous pouvez également utiliser append plutôt que d'affecter explicitement les valeurs à leurs index:

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 que la capacité (espace alloué) est initialisée avec le nombre d'éléments de m. Ceci est fait pour que append n'ait pas besoin d'allouer de mémoire chaque fois que la capacité de la tranche v s'épuise.

Vous pouvez également make la tranche sans la valeur de capacité et laisser append allouer la mémoire pour elle-même.

43
nemo

Vous pouvez utiliser ce maps package:

go get https://github.com/drgrib/maps

Ensuite, tout ce que vous devez appeler est

values := maps.GetValuesIntString(m)

Il est compatible avec le type pour cette combinaison map courante. Vous pouvez generate autres fonctions de type sécurisé pour tout autre type de map à l'aide de l'outil mapper dans le même package.

Divulgation complète: je suis le créateur de ce paquet. Je l'ai créé parce que je me suis retrouvé à réécrire ces fonctions pour map à plusieurs reprises.

0
Chris Redford

Autant que je sache, go n'a pas de méthode de moyen pour concaténer des chaînes/octets dans une chaîne résultante sans faire au moins/deux/copies.

Vous devez actuellement développer un octet [] car toutes les valeurs de chaîne sont constantes, PUIS 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 part pourrait avoir une référence. à l'adresse accompagnant l'octet [].

Si un octet [] convient, vous pouvez obtenir une très légère avance sur la fonction octets.Join en faisant une attribution et en faisant la copie vous appelle 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)
}
0
Michael J. Evans