【问题标题】:Compare two array of hashes with same keys比较两个具有相同键的哈希数组
【发布时间】:2016-03-11 11:06:05
【问题描述】:

我有 2 个具有相同键但值不同的哈希数组。

A = [{:a=>1, :b=>4, :c=>2},{:a=>2, :b=>1, :c=>3}]
B = [{:a=>1, :b=>1, :c=>2},{:a=>1, :b=>3, :c=>3}]

我正在尝试使用它们的键比较 A 中的第一个散列和 B 中的第一个散列,依此类推,如果它们不匹配,则确定哪个键和哪个值不匹配。请帮忙。

    A.each_key do |key|
      if A[key] ==  B[key]
        puts "#{key} match"
      else
        puts "#{key} dont match"

【问题讨论】:

    标签: arrays ruby hash


    【解决方案1】:

    我不确定您要进行哪些比较,因此我将展示回答不同问题的方法。您想对两个散列数组进行成对比较,但这实际上并不比仅比较两个散列更困难,我稍后会展示。现在,假设您只想比较两个哈希:

    h1 = {:a=>1, :b=>4, :c=>2, :d=>3 }
    h2 = {:a=>1, :b=>1, :c=>2, :e=>5 }
    

    h1h2(或两者)中有哪些键?

    h1.keys | h2.keys
      #=> [:a, :b, :c, :d, :e]
    

    Array#|

    两个哈希中的键是什么?

    h1.keys & h2.keys
      #=> [:a, :b, :c] 
    

    Array#&

    h1 中有哪些键,h2 中没有?

    h1.keys - h2.keys
      #=> [:d] 
    

    Array#-

    h2 中有哪些键,h1 中没有?

    h2.keys - h1.keys #=> [:e] 
    

    哪些键只在一个哈希中?

    (h1.keys - h2.keys) | (h2.keys - h1.keys)
      #=> [:d, :e]
    

    (h1.keys | h2.keys) - (h1.keys & h2.keys)
    

    哪些键在两个哈希中并且在两个哈希中具有相同的值?

    (h1.keys & h2.keys).select { |k| h1[k] == h2[k] }
      #=> [:a, :c] 
    

    Array#select

    什么键在两个哈希中并且在两个哈希中具有不同的值?

    (h1.keys & h2.keys).reject { |k| h1[k] == h2[k] }
      #=> [:b] 
    

    假设现在我们有两个哈希数组:

    a1 = [{:a=>1, :b=>4, :c=>2, :d=>3 }, {:a=>2, :b=>1, :c=>3, :d=>4}]
    a2 = [{:a=>1, :b=>1, :c=>2, :e=>5 }, {:a=>1, :b=>3, :c=>3, :e=> 6}]
    

    并希望成对比较哈希值。要做到这一点,首先需要上面感兴趣的计算并将其包装在一个方法中。例如:

    def keys_in_both_with_different_values(h1, h2)
      (h1.keys & h2.keys).reject { |k| h1[k] == h2[k] }
    end
    

    然后写:

    a1.zip(a2).map { |h1,h2| keys_in_both_with_different_values(h1, h2) }
      #=> [[:b], [:a, :b]]
    

    Enumerable#zip

    【讨论】:

      【解决方案2】:

      当你处理一个数组时,你应该引用一个带有开闭括号'[]'的元素,如

      A[index at which lies the element you are looking for]
      

      如果要访问散列中的元素,则要使用带有相应键的开闭括号,如

      A[:a] 
      

      (引用与键':a'对应的值,它是一个类型符号。)

      在这种情况下,所讨论的数组使得哈希嵌套在数组中。例如,表达式 B[0][:c] 将给出 2。

      要将 A 中的第一个哈希值与 B 中的第一个哈希值、A 中的第二个哈希值与 B 中的第二个哈希值进行比较等等,您可以对 Array 对象使用 each_with_index 方法,如下所示;

      A = [{:a=>1, :b=>4, :c=>2},{:a=>2, :b=>1, :c=>3}]
      B = [{:a=>1, :b=>1, :c=>2},{:a=>1, :b=>3, :c=>3}]
      sym = [:a, :b, :c]
      
      A.each_with_index do |hash_a, idx_a|
        sym.each do |sym|
          if A[idx_a][sym] == B[idx_a][sym]
            puts "Match found! (key -- :#{sym}, value -- #{A[idx_a][sym]})"
          else
            puts "No match here."
          end 
        end
      end
      

      它正在根据作为符号的键按以下顺序检查值; :a -> :b -> :c -> :a -> :b -> :c 这将打印出来;

      Match found! (key -- :a, value -- 1)
      No match here.
      Match found! (key -- :c, value -- 2)
      No match here.
      No match here.
      Match found! (key -- :c, value -- 3)
      

      如果您不熟悉each_with_index 方法,它可能看起来有点神秘。 如果您对此感到不舒服,您可能需要检查一下;
      http://apidock.com/ruby/Enumerable/each_with_index

      最后但同样重要的是,不要忘记在代码块的末尾(即 do/end 之间的代码)和代码中的 if 语句添加“end”。

      希望对你有帮助。

      【讨论】:

        【解决方案3】:

        由于您正在比较数组的元素...

        A.each_with_index do |hasha, index|
          hashb = B[index]
          hasha.each_key do |key|
            if hasha[key] == hashb[key]
              puts "in array #{index} the key #{key} matches"
            else
              puts "in array #{index} the key #{key} doesn't match"
            end
          end
        end
        

        编辑 - 添加了一个缺失的end

        【讨论】:

        • 谢谢你,史蒂夫。这很有帮助!
        • 太棒了!如果您喜欢这个答案,请毫不犹豫地接受它(答案旁边有一个选项可以这样做)
        猜你喜欢
        • 2019-05-03
        • 2012-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多