Si tengo un mapa m, ¿hay una mejor manera de obtener una porción de los valores v entonces?
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)
}
¿Existe una función incorporada en un mapa? ¿Hay una función en un paquete Go, o este es el mejor código para hacer si tengo que hacerlo?
_
conidx
y utilizaridx-1
la hora de asignar los valores de división.Respuestas:
Lamentablemente no. No hay una forma incorporada de hacer esto.
Como nota al margen, puede omitir el argumento de capacidad en la creación de su segmento:
v := make([]string, len(m))
Se da a entender que la capacidad es la misma que la longitud aquí.
fuente
Como una adición a la publicación de Jimt:
También puede usar en
append
lugar de asignar explícitamente los valores a sus índices: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) }
Tenga en cuenta que la longitud es cero (todavía no hay elementos presentes) pero la capacidad (espacio asignado) se inicializa con el número de elementos de
m
. Esto se hace paraappend
que no sea necesario asignar memoria cada vez que sev
agote la capacidad del segmento .También puede
make
cortar el segmento sin el valor de capacidad y dejarappend
asignar la memoria por sí mismo.fuente
make([]appsv1.Deployment, len(d))
agregará a un grupo de elementos vacíos que se crearon cuando asignólen(d)
elementos vacíos.Hasta donde yo sé, go no tiene un método de concatenación de cadenas / bytes en una cadena resultante sin hacer al menos / dos / copias.
Actualmente tiene que aumentar un [] byte ya que todos los valores de cadena son constantes, LUEGO debe usar la cadena incorporada para que el lenguaje cree un objeto de cadena 'bendecido', que copiará el búfer para ya que algo en algún lugar podría tener una referencia a la dirección que respalda el byte [].
Si un byte [] es adecuado, entonces puede obtener una ventaja muy leve sobre los bytes. Únase a la función haciendo una asignación y haciendo las llamadas de copia usted mismo.
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) }
fuente
Puede utilizar este
maps
paquete:go get https://github.com/drgrib/maps
Entonces todo lo que tienes que llamar es
Es de tipo seguro para esa
map
combinación común . Puede utilizargenerate
otras funciones de tipo seguro para cualquier otro tipo demap
uso de lamapper
herramienta en el mismo paquete.Divulgación completa: soy el creador de este paquete. Lo creé porque me encontré reescribiendo estas funciones
map
repetidamente.fuente
No necesariamente mejor, pero la forma más limpia de hacer esto es definiendo tanto la LONGITUD y la CAPACIDAD del corte como
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) }
Ejemplo completo:
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 }
Solución simple pero con muchas trampas. Lea esta publicación de blog para obtener más detalles: https://web3.coach/golang-how-to-convert-map-to-slice-three-gotchas
fuente