在原始地图上进行测距时,在地图中重命名键的惯用方法

时间:2017-07-16 19:31:08

标签: go

我正在尝试使用其他地图o的键和值重命名地图r的键。

以下尝试似乎失败的原因我认为与我正在修改地图同时还要覆盖它的事实有关 - 我得到一个额外的blank密钥。

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

o := make(map[string]string) // original map
r := make(map[string]string) // replacement map original -> destination keys

o["a"] = "x"
o["b"] = "y"

r["a"] = "1"
r["b"] = "2"

fmt.Println(o) // -> map[a:x b:y]

for k, v := range o {
    o[r[k]] = v
}

delete(o, "a")
delete(o, "b")

fmt.Println(o) // -> map[1:x 2:y :y]

我希望打印map[1:x 2:y]

3 个答案:

答案 0 :(得分:2)

如果您在同一时间范围内修改目标地图,则会出现意外行为,其中有一个空值键。之前我已经看过了(它发生的时间并不总是如此)。我没有研究过它(可能是SO成员可以在这里阐明一些内容)。

如果您对源地图进行了范围扩展并更新了目标地图,则会获得所需的行为。

for k, v := range r {
    o[v] = o[k]
    delete(o, k)
}

输出:

Modified map: map[1:x 2:y]

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

答案 1 :(得分:1)

简单地遍历其他地图:

o := make(map[string]string) // original map
r := make(map[string]string) // replacement map original -> destination keys

o["a"] = "x"
o["b"] = "y"

r["a"] = "1"
r["b"] = "2"

fmt.Println(o) // -> map[a:x b:y]

for k, v := range r {
    o[v] = o[k]
    delete(o, k)
}
fmt.Println(o) // -> map[1:x 2:y]

答案 2 :(得分:0)

PEBKAC一如既往,首先检查替换密钥是否存在于替换地图中并且一下子删除它,这似乎很好地解决了这个问题

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