【问题标题】:Idiomatic way of renaming keys in map while ranging over the original map在原始地图范围内重命名地图中的键的惯用方式
【发布时间】:2017-07-16 19:31:08
【问题描述】:

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

下面的尝试似乎失败了,原因我猜想与我在修改地图的同时也在覆盖它的事实有关——我得到了一个额外的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]

【问题讨论】:

    标签: go


    【解决方案1】:

    如果您同时对目标地图进行范围和修改,则会出现意想不到的行为,即空键和值。我以前见过(有时并不总是发生)。我没有研究过它(可能是其他 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

    【讨论】:

      【解决方案2】:

      只需遍历另一张地图:

      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]
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多