【问题标题】:Non destructive way of deleting a key from a hash从哈希中删除密钥的非破坏性方法
【发布时间】:2012-11-09 06:05:21
【问题描述】:

是否有从哈希中删除键值对的非破坏性方法?

例如,如果你这样做了

original_hash = {:foo => :bar}
new_hash = original_hash
new_hash = new_hash.reject{|key, _| key == :foo}

original_hash = {:foo => :bar}
new_hash = original_hash
new_hash = new_hash.dup
new_hash.delete(:foo)

然后original_hash 不变,new_hash 变了,但它们有点冗长。但是,如果你这样做了

original_hash = {:foo => :bar}
new_hash = original_hash
new_hash.delete(:foo)

然后original_hash 被更改,这不是我想要的。

有没有一种方法可以满足我的要求?

【问题讨论】:

  • original_hash is 在您的第一个示例中使用delete_if 进行了更改。此外,new_hash 在第二个示例中使用delete 获取与:foo 关联的值,即:bar,而不是哈希本身。
  • @shioyama 谢谢你! >_

标签: ruby hash side-effects


【解决方案1】:

是的,你想要reject

new_hash = original_hash.reject{|key, _| key == :foo}

【讨论】:

    【解决方案2】:

    ActiveSupport 提供哈希扩展:Hash#except。它允许您在不修改原始键的情况下返回除指定键之外的新哈希。

    假设您已经安装了 active_support gem:

    ruby-1.9.3> require 'active_support/core_ext/hash/except.rb'
     => true
     ruby-1.9.3> a = {x: 2, y: 1, z: 3}
     => {:x=>2, :y=>1, :z=>3} 
    ruby-1.9.3> b = a.except(:x)
     => {:y=>1, :z=>3} 
    ruby-1.9.3> c = a.except(:x, :y)
     => {:z=>3} 
    ruby-1.9.3> a
     => {:x=>2, :y=>1, :z=>3} 
    ruby-1.9.3> b
     => {:y=>1, :z=>3} 
    ruby-1.9.3> c
     => {:z=>3} 
    

    【讨论】:

    • 我不使用 ActiveSupport,但他们提供这样的方法这一事实很好地证明了 Ruby 本身没有这样的方法。
    【解决方案3】:

    问题在于 new_hash 是一个引用,除非您明确告诉 Ruby 复制该对象。你使用 dup 走在正确的轨道上,我唯一推荐的就是这样做

    new_hash = original_hash.dup 
    

    因为我认为你在做什么更明确。

    【讨论】:

      【解决方案4】:

      如何链接 dup 以使其不那么冗长?

      new_hash = original_hash.dup.delete_if{|key, _| key == :foo}
      

      【讨论】:

        【解决方案5】:
        original_hash.clone.tap {|h| h.delete key}
        

        tap 可以说没有声明一个新变量那么笨重,主要是因为它在同一行。

        我认为clonedup 更明确地是一个平面副本,当然对于散列来说它几乎没有什么区别。

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        猜你喜欢
        • 2021-01-31
        • 2013-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-10
        • 1970-01-01
        • 2018-11-17
        • 2012-05-09
        相关资源
        最近更新 更多