Copier tous les éléments d'une carte dans une autre
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
}
Y a-t-il une façon plus idiomatique de le faire?
copy
fonctionne uniquement sur les tranches (et string
comme une source).
3 réponses
Cela ressemble à une excellente façon de me faire cela. Je ne pense pas que Copier une carte dans une autre soit assez commun pour avoir une solution à un seul revêtement.
L'utilisation d'une simple boucle for range
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. Cartes de grandir pour accueillir le nombre d'éléments stockés. 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 nouvelle.
Si votre carte est grande, vous pouvez accélérer la copie des éléments si vous pouvez créer la carte de destination ayant une capacité suffisante pour éviter de ressasser et de réallouer (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 en utilisant reflect
Paquet:
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 cartes et si la destination n'est pas nil
. Test il:
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 sur la Aller de l'aire de Jeux):
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}