【问题标题】:Find missing keys from a nested hash in comparison to another nested hash与另一个嵌套散列相比,从嵌套散列中查找缺失的键
【发布时间】:2014-09-13 09:56:19
【问题描述】:

我有两个嵌套的散列(hash1、hash2),它们碰巧是从 yml 文件生成的散列。我需要找到 hash1 中存在但 hash2 中不存在的所有键(完整的父链)。

鉴于这两个哈希,输出应该是 hash_diff。

hash1 = {"A" => 1, "B" => {"C" => 2, "D" => 3} , "E" => 1} 
hash2 = {"A" => 1, "B" => {"C" => 2} }
hash_diff = {"B" => {"D" => 3}, "E" => 1} 

请注意,我想要类似哈希差异的东西,它只考虑键,而不考虑值。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 hash


    【解决方案1】:

    这里是解决方案。虽然我修改了原来的hash1
    所以用法是:

    hash_diff(hash1,hash2)
    hash_diff_var = hash1
    
    def self.hash_diff_helper(hash1,hash2)
        hash1.each_pair do |k,v|
          if v.is_a?(Hash) && hash2.key?(k)
            hash_diff_helper(v,hash2[k])
          elsif !v.is_a?(Hash) && hash2.key?(k)
            hash1.delete(k)
          end
        end
      end
    
      def self.hash_diff(hash1,hash2)
        hash_diff_helper(hash1,hash2)
        hash1.select!{|k,v| v.present?}
      end
    

    【讨论】:

      【解决方案2】:

      我会修改 Hash 以获得你想要的功能,所以本质上是一个合并,当 hash2 中不存在时返回 nil,然后在 hash 上实现紧凑:

      class ::Hash
           def deep_nil_merge(second)
              merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : nil }
              self.merge(second, &merger)
           end
      
        def compact
          delete_if{|k, v|
      
            (v.is_a?(Hash) and v.respond_to?('empty?') and v.compact.empty?) or
                (v.nil?)  or
                (v.is_a?(String) and v.empty?)
          }
        end
      
      
      end
      

      然后运行

      hash1.deep_nil_merge(hash2).compact
      

      【讨论】:

        【解决方案3】:

        有一些宝石可以帮助您实现这一目标。

        如果你只想要一个纯粹的差异,https://github.com/Blargel/easy_diff 是一个不错的选择。它为您提供了已添加和删除的内容以产生影响。

        一个更强大的选项是https://github.com/liufengyun/hashdiff,它不会修改 Hash 对象,而是返回一个包含所有点符号差异的数组。

        【讨论】:

        • 请注意 link-only answers 是不鼓励的,所以答案应该是寻找解决方案的终点(相对于另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。
        • 添加每个摘要。
        猜你喜欢
        • 1970-01-01
        • 2013-07-08
        • 2014-07-28
        • 2013-03-14
        • 2017-10-02
        • 2018-11-07
        • 2013-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多