J'essaie de copier le contenu d'une carte (amap
) dans une autre (aSuperMap
), puis d'effacer amap
pour qu'il puisse prendre de nouvelles valeurs à la prochaine itération/boucle. Le problème est que vous ne pouvez pas effacer la carte sans effacer sa référence dans la super-carte également . Voici un pseudo code.
for something := range fruits{
aMap := make(map[string]aStruct)
aSuperMap := make(map[string]map[string]aStruct)
for x := range something{
aMap[x] = aData
aSuperMap[y] = aMap
delete(aMap, x)
}
//save aSuperMap
saveASuperMap(something)
}
J'ai aussi essayé des trucs dynamiques mais il y a évidemment une erreur (impossible d'affecter à zéro)
aSuperMap[y][x] = aData
La question est de savoir comment puis-je créer une carte associative? Dans PHP, j'utilise simplement aSuperMap [y] [x] = aData. Il semble que Golang n'a pas de méthode évidente. Si je supprime delete(aMap, x)
, sa référence à la super-carte est également supprimée. Si je ne le supprime pas, la super-carte se termine par des données en double. En gros, chaque boucle obtient aMap
avec la nouvelle valeur et toutes les anciennes valeurs.
Vous ne copiez pas la carte, mais la référence à la carte. Votre delete
modifie donc les valeurs de votre carte d'origine et de la super carte. Pour copier une carte, vous devez utiliser une boucle for
comme ceci:
for k,v := range originalMap {
newMap[k] = v
}
Voici un exemple tiré de la documentation SO maintenant retirée:
// Create the original map
originalMap := make(map[string]int)
originalMap["one"] = 1
originalMap["two"] = 2
// Create the target map
targetMap := make(map[string]int)
// Copy from the original map to the target map
for key, value := range originalMap {
targetMap[key] = value
}
Extrait de Maps - Copier une carte . L'auteur original était JepZ . Les détails de l'attribution sont disponibles sur la page contributor . La source est sous licence CC BY-SA 3.0 et se trouve dans l'archive Documentation . Sujet de référence ID: 732 et exemple ID: 9834.
J'utiliserais la récursion au cas où vous puissiez copier en profondeur la map
et éviter les mauvaises surprises si vous changiez un élément map
qui est lui-même une map
.
Voici un exemple dans utils.go:
package utils
func CopyMap(m map[string]interface{}) map[string]interface{} {
cp := make(map[string]interface{})
for k, v := range m {
vm, ok := v.(map[string]interface{})
if ok {
cp[k] = CopyMap(vm)
} else {
cp[k] = v
}
}
return cp
}
Et son fichier de test (utils_test.go):
package utils
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestCopyMap(t *testing.T) {
m1 := map[string]interface{}{
"a": "bbb",
"b": map[string]interface{}{
"c": 123,
},
}
m2 := CopyMap(m1)
m1["a"] = "zzz"
delete(m1, "b")
require.Equal(t, map[string]interface{}{"a": "zzz"}, m1)
require.Equal(t, map[string]interface{}{
"a": "bbb",
"b": map[string]interface{}{
"c": 123,
},
}, m2)
}
Il doit être assez facile à réadapter si vous avez besoin que la clé map
soit autre chose que string
.
Copie d’élément individuel, cela semble fonctionner pour moi avec un exemple simple.
maps := map[string]int {
"alice":12,
"jimmy":15,
}
maps2 := make(map[string]int)
for k2,v2 := range maps {
maps2[k2] = v2
}
maps2["miki"]=Rand.Intn(100)
fmt.Println("maps: ",maps," vs. ","maps2: ",maps2)
Vous devez copier manuellement chaque paire clé/valeur dans une nouvelle map
. Il s’agit d’une boucle que les utilisateurs doivent reprogrammer à tout moment pour obtenir une copie complète d’un map
.
Vous pouvez automatiquement générer cette fonction en installant mapper
à partir de maps
package à l'aide de
go get -u github.com/drgrib/maps/cmd/mapper
et courir
mapper -types string:aStruct
qui générera le fichier map_float_astruct.go
contenant non seulement une (profonde) Copy
pour votre carte, mais également d'autres fonctions map
"manquantes" ContainsKey
, ContainsValue
, GetKeys
et GetValues
:
func ContainsKeyStringAStruct(m map[string]aStruct, k string) bool {
_, ok := m[k]
return ok
}
func ContainsValueStringAStruct(m map[string]aStruct, v aStruct) bool {
for _, mValue := range m {
if mValue == v {
return true
}
}
return false
}
func GetKeysStringAStruct(m map[string]aStruct) []string {
keys := []string{}
for k, _ := range m {
keys = append(keys, k)
}
return keys
}
func GetValuesStringAStruct(m map[string]aStruct) []aStruct {
values := []aStruct{}
for _, v := range m {
values = append(values, v)
}
return values
}
func CopyStringAStruct(m map[string]aStruct) map[string]aStruct {
copyMap := map[string]aStruct{}
for k, v := range m {
copyMap[k] = v
}
return copyMap
}
Divulgation complète: je suis le créateur de cet outil. Je l'ai créé et son package contenant parce que je me suis retrouvé à réécrire constamment ces algorithmes pour Go map
pour différentes combinaisons de types.