【问题标题】:ruby - How to replace a hash key/value with another key/valueruby - 如何用另一个键/值替换散列键/值
【发布时间】:2016-11-04 03:28:01
【问题描述】:

我有一个哈希

  hash = {"some_wierd_name"=>"cheesemonster", .....}

我希望这个哈希为

  hash = {"preferred_name"=>"cheesemonster", ......}

最快的方法是什么?

【问题讨论】:

  • 哈希是有序的,你需要保留这个顺序吗?
  • @mu 提出了一个很好的观点。也许你想要{ "preferred_name" => hash.delete("some_weird_name") }.merge hash

标签: ruby


【解决方案1】:
hash["preferred_name"] = hash.delete("some_wierd_name")

哈希键是 frozen 字符串,它们不能就地修改,并且不能从对象中删除冻结状态。也就是说,prependreplace 的技巧将不起作用,导致:

RuntimeError: can't modify frozen String

因此,只有一种可能:删除旧值并插入新值。

【讨论】:

  • 如果封装在方法中,需要hash作为最后一行。
【解决方案2】:
hash = {"some_wierd_name"=>"cheesemonster"}

hash["preferred_name"] = hash["some_wierd_name"]
hash.delete("some_wierd_name")

【讨论】:

  • 请注意(因为hash.delete("some_wierd_name") => "cheesemonster")如果它被打包在一个方法中,hash 需要作为最后一行。
【解决方案3】:
  • 如果我们希望同时替换键/值,可以使用 rails except 方法轻松完成。您也可以使用 delete 方法,但一次只使用一个键/值对,但使用 except 可以删除 2 个或更多键/值对。

    hash = {a: 1, b:2, c: 3}
    hash.except!(:a)[:d] = 4 
    and it is similar to these two following line
    hash.except!(:a) 
    hash[:d] = 4
    hash = {:b=>2, :c=>3, :d=>4}
    
  • 仅更改哈希的键,值保持不变。也可以使用拒绝。 reject 和 delete_if 是一样的。

    hash[:e] = hash.delete(:d) 
         or 
    temp = hash[d]
    hash.delete_if{|key| key ==:d }
    hash[:e] = temp
    hash = {:b=>2, :c=>3, :e=>4}
    
  • 仅更改值,键保持不变。这个很简单。

    hash[:e] = 5
    

参考文献:

【讨论】:

    【解决方案4】:

    对于单个键,使用delete

    hash["preferred_name"] = hash.delete("some_wierd_name")
    

    如果您需要更新所有密钥,我建议使用注入

    new_hash = hash.inject({}) do |returned_hash, (key, value)|
      returned_hash[key] = value.upcase;
      returned_hash
    end
    

    【讨论】:

    • 自我回答不是问题,一般不会被人反对。此外,答案是正确且相当完整的,无需担心。
    • 作为一个小小的补充,您也可以使用each_with_object 代替inject 来删除块中的第二行。
    • @HolgerJust,如果这是一个具有挑战性的问题,我会同意你的看法,但这个问题不是。我已经在 SO 上多次看到过这种重命名密钥的技术。
    • 为什么是value.upcase?当您没有真正注射时,为什么不使用each_with_object({})?或者,如果您正在注入,请使用 h.merge(k => v.upcase) 作为块。而且您的 inject 版本没有重命名任何键,它正在修改值。
    • @Sean,我认为“无耻的抢点”相当苛刻。这里的一些非常有经验的 Rubiest 会定期发布问题,然后立即发布答案。实际上,他们是在说,“这是我能想到的最好的方法。有更好的方法吗?”通常这是他们在工作中遇到的具有挑战性的问题。它与代表无关。
    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 2012-07-01
    • 2011-10-19
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多