在覆盖原始地图时重命名地图中的键的惯用方法

sal*_*ent 7 go

我正在尝试o使用另一个映射的键和值重命名映射的键r

\n\n

下面的尝试似乎失败了,因为我猜想与我正在修改地图同时也在其上进行范围\xe2\x80\x94有关,我得到了一个额外的blank密钥。

\n\n

我可以简单地将地图复制到新的目标地图,但是该地图是更复杂的结构 \xe2\x80\x94 的一部分,因此任何尝试都需要我对该结构进行某种递归深层复制,我宁愿避免。

\n\n
o := make(map[string]string) // original map\nr := make(map[string]string) // replacement map original -> destination keys\n\no["a"] = "x"\no["b"] = "y"\n\nr["a"] = "1"\nr["b"] = "2"\n\nfmt.Println(o) // -> map[a:x b:y]\n\nfor k, v := range o {\n    o[r[k]] = v\n}\n\ndelete(o, "a")\ndelete(o, "b")\n\nfmt.Println(o) // -> map[1:x 2:y :y]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我期待着打印出来map[1:x 2:y]

\n

jee*_*tkm 5

如果您同时范围和修改目标地图,则会出现意外行为,即空键与值。我以前见过这种情况(有时会发生,但并非总是如此)。我还没有研究过它(也许其他 SO 成员可以在这里阐明一些情况)。

如果您确实覆盖源地图并更新目标地图,您将获得所需的行为。

for k, v := range r {
    o[v] = o[k]
    delete(o, k)
}
Run Code Online (Sandbox Code Playgroud)

输出:

Modified map: map[1:x 2:y]
Run Code Online (Sandbox Code Playgroud)

播放链接: https: //play.golang.org/p/heVbZFe0Nu


sal*_*ent 0

PEBKAC 一如既往,这似乎可以很好地解决这个问题,首先检查替换密钥是否存在于替换映射中,然后一举删除它

for k, v := range o {
    if _, ok := r[k]; ok {
        o[r[k]] = v
        delete(o, k)
    }
}
Run Code Online (Sandbox Code Playgroud)