Donné
var dst, src map[K]V
Je peux copier toutes les entrées de src
dans dst
en faisant
for k, v := range src {
dst[k] = v
}
Existe-t-il une manière plus idiomatique de procéder?
copy
ne fonctionne que sur les tranches (et string
comme source).
Cela ressemble à une manière parfaitement fine de me faire ça. Je ne pense pas que copier une carte dans une autre soit assez courant pour avoir une solution à une ligne.
En utilisant un simple for range
loop est la solution la plus efficace.
Notez qu'un copy
intégré ne peut pas simplement copier la mémoire de src
à l'adresse de dst
car ils peuvent avoir une disposition de mémoire entièrement différente. Les cartes s'agrandissent pour accueillir le nombre d'éléments qu'elles contiennent. Ainsi, par exemple, si vous avez une carte avec un million d'éléments, elle occupe beaucoup plus de mémoire qu'une nouvelle carte fraîchement créée, et donc un copy
intégré ne peut pas simplement copier de la mémoire sans allouer de nouveaux.
Si votre carte est grande, vous pouvez accélérer la copie des éléments si vous pouvez créer la carte de destination avec une capacité suffisamment grande pour éviter le ressassement et la réaffectation (la capacité initiale ne limite pas sa taille), par exemple:
dst := make(map[K]V, len(src))
for k, v := range src {
dst[k] = v
}
Si les performances ne sont pas un problème (par exemple, vous travaillez avec de petites cartes), une solution générale peut être créée à l'aide du package 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))
}
}
Cette solution ne vérifie pas si les arguments sont vraiment des mappages et si la destination n'est pas nil
. Le tester:
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)
Sortie (essayez-le sur le Go Playground ):
map[1:one 2:two]
map[one:1 two:2]
Vous pouvez utiliser 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}