dictionary - simbolos - que es un mapa cartografico
Copiando todos los elementos de un mapa en otro (3)
Esa parece una forma perfectamente buena de hacerme esto. No creo que copiar un mapa en otro sea lo suficientemente común como para tener una solución de una sola línea.
Dado
var dst, src map[K]V
Puedo copiar todas las entradas de src
a dst
haciendo
for k, v := range src {
dst[k] = v
}
¿Hay una manera más idiomática de hacer esto?
copy
solo funciona en sectores (y string
como fuente).
Podría usar github.com/linkosmos/mapop
input := map[string]interface{}{
"Key1": 2,
"key3": nil,
"val": 2,
"val2": "str",
"val3": 4,
}
input2 := map[string]interface{}{
"a2": "str",
"a3": 4,
}
input = mapop.Merge(input, input2)
input{"Key1": 2, "key3": nil, "val": 2, "val2": "str", "val3": 4, "a2": "str", "a3": 4}
Usar un bucle de for range
simple es la solución más eficiente.
Tenga en cuenta que una copy
integrada no puede simplemente copiar la memoria de src
a la dirección de dst
porque pueden tener un diseño de memoria completamente diferente. Los mapas crecen para acomodar la cantidad de elementos almacenados en ellos. Entonces, por ejemplo, si tiene un mapa con un millón de elementos, ocupa mucha más memoria que un nuevo mapa recién creado, por lo que una copy
incorporada no podría simplemente copiar memoria sin asignar nueva.
Si su mapa es grande, puede acelerar los elementos de copia si puede crear un mapa de destino que tenga una capacidad lo suficientemente grande como para evitar el reajuste y la reasignación (la capacidad inicial no se ajusta a su tamaño), por ejemplo:
dst := make(map[K]V, len(src))
for k, v := range src {
dst[k] = v
}
Si el rendimiento no es un problema (por ejemplo, si está trabajando con mapas pequeños), se puede crear una solución general utilizando el paquete de reflect
:
func MapCopy(dst, src interface{}) {
dv, sv := reflect.ValueOf(dst), reflect.ValueOf(src)
for _, k := range sv.MapKeys() {
dv.SetMapIndex(k, sv.MapIndex(k))
}
}
Esta solución no verifica si los argumentos son realmente mapas y si el destino no es nil
. Probándolo:
m1 := map[int]string{1: "one", 2: "two"}
m2 := map[int]string{}
MapCopy(m2, m1)
fmt.Println(m2)
m3 := map[string]int{"one": 1, "two": 2}
m4 := map[string]int{}
MapCopy(m4, m3)
fmt.Println(m4)
Salida (pruébalo en el área de juegos Go ):
map[1:one 2:two]
map[one:1 two:2]