2016-10-04 82 views
2

我有兩個不同的數組,每個數組都包含不同的哈希值。ruby​​比較不同陣列中哈希值之間的值

new_array1 = [ 
        {:index=>4, :column=>0, :ID=>"ABC"}, 
        {:index=>4, :column=>1, :ID=>"XYZ"}, 
        {:index=>4, :column=>2, :ID=>"BCD-1547"} 
       ] 


new_array2 = [ 
        {:index=>4, :column=>0, :ID=>"ABC"}, 
        {:index=>4, :column=>1, :ID=>"IJK"}, 
        {:index=>4, :column=>2, :ID=>"BCD-1547"} 
       ] 

我想:ID鍵的值在new_array1 VS值在new_array2只有當:index:column值是相同的比較。

ie) 
if (new_array1[0][:index] == new_array2[0][:index]) and (new_array1[0][:column] == new_array2[0][:column]) 
    if(new_array1[0][:ID] == new_array2[0][:ID]) 
     # do something 
    end 
end 

有沒有辦法循環兩個數組中的所有散列並找到匹配?或者可能是一個更優雅的方式來做到這一點在紅寶石?

回答

2

這將返回匹配的散列數組:

res = new_array1.inject([]) { |memo, hash| memo << hash if new_array2.any? { |hash2| hash[:ID] == hash2[:ID] && hash[:index] == hash2[:index] && hash[:column] == hash2[:column] }; memo } 
# => [{:index=>4, :column=>0, :ID=>"ABC"}, {:index=>4, :column=>1, :ID=>"XYZ"}, {:index=>4, :column=>2, :ID=>"BCD-1547"}] 

res.each do |hash| 
    # do something 
end 

如果new_array1中的項目具有相同的indexcolumnID鍵作爲在new_array2它將被包含的任何項目。

你也可以simpify如果這些都是使用==比較平等的哈希值的唯一鍵:

res = new_array1.inject([]) { |memo, hash| memo << hash if new_array2.any? { |hash2| hash == hash2 }; memo } 

inject方法,鋸齒,也被稱爲reduce,需要收集並創建一個新的價值從它,每次調用給inject的塊被調用時,它被賦予集合的下一個元素和前一個塊的返回值(第一次調用該塊時,它被賦予傳遞給inject的種子值)。這可以讓你建立一個類似於遞歸的值。

還有的inject這裏一些例子:Need a simple explanation of the inject method

any?方法將返回true,一旦給定塊對於任何給定的集合元素返回true。如果塊從不返回true,則any?返回false。所以:

[0,0,0,1,0].any? { |num| num == 1 } # => true 
[0,0,0,0,0].any? { |num| num == 1 } # => false 
+0

1.考慮使用'each_with_object'和2.這有助於「'#做點什麼」? – mudasobwa

+0

@mudasobwa他們可以迭代'res'做些事情,我會更新答案。 – Kris

+0

這正是我要找的,謝謝! 你能解釋一下'注入([])'和'任何嗎?' – danynl

0
[new_array1, new_array2].map do |a| 
    a.group_by { |e| [e[:index], e[:column]] } 
end.reduce do |f, l| 
    f.merge(l) { |_, f, l| [f.first[:ID], l.first[:ID]] } 
end 
# => { 
#  [ 4, 0 ] => [ 
#   [0] "ABC", 
#   [1] "ABC" 
#  ], 
#  [ 4, 1 ] => [ 
#   [0] "XYZ", 
#   [1] "IJK" 
#  ], 
#  [ 4, 2 ] => [ 
#   [0] "BCD-1547", 
#   [1] "BCD-1547" 
#  ] 
# } 

do_something unless f.first[:ID] == l.first[:ID]而不是[f.first[:ID], l.first[:ID]]最後條款中做任何你想要的。

0

如果所有哈希值具有相同的三把鑰匙,並沒有其他按鍵,它簡直是

new_array1 & new_array2 
    #=> [{:index=>4, :column=>0, :ID=>"ABC"}, 
    # {:index=>4, :column=>2, :ID=>"BCD-1547"}] 

如果哈希可能有其他的鍵,以及,你可以寫出如下。

new_array1 = [{:index=>4, :column=>0, :ID=>"ABC",  :pet=>"cat"}, 
       {:index=>4, :column=>1, :ID=>"XYZ",  :bet=>"red"}, 
       {:index=>4, :column=>2, :ID=>"BCD-1547", :met=>"Betty"}] 

new_array2 = [{:index=>4, :column=>0, :ID=>"ABC",  :tree=>"maple"}, 
       {:index=>4, :column=>1, :ID=>"IJK",  :colour=>"blue"}, 
       {:index=>4, :column=>2, :ID=>"BCD-1547", :car=>"beemer"}] 

keys = [:index,:column,:ID] 
h1 = new_array1.each_with_object({}) { |g,h| h[g.select { |k,_| keys.include? k }] = g } 
    #=> {{:index=>4, :column=>0, :ID=>"ABC"}=> 
    #  {:index=>4, :column=>0, :ID=>"ABC", :pet=>"cat"}, 
    # {:index=>4, :column=>1, :ID=>"XYZ"}=> 
    #  {:index=>4, :column=>1, :ID=>"XYZ", :bet=>"red"}, 
    # {:index=>4, :column=>2, :ID=>"BCD-1547"}=> 
    #  {:index=>4, :column=>2, :ID=>"BCD-1547", :met=>"Betty"}} 
h2 = new_array2.each_with_object({}) { |g,h| h[g.select { |k,_| keys.include? k }] = g } 
    #=> {{:index=>4, :column=>0, :ID=>"ABC"}=> 
    #  {:index=>4, :column=>0, :ID=>"ABC", :tree=>"maple"}, 
    # {:index=>4, :column=>1, :ID=>"IJK"}=> 
    #  {:index=>4, :column=>1, :ID=>"IJK", :colour=>"blue"}, 
    # {:index=>4, :column=>2, :ID=>"BCD-1547"}=> 
    #  {:index=>4, :column=>2, :ID=>"BCD-1547", :car=>"beemer"}} 
(h1.keys & h2.keys).map { |k| [h1[k], h2[k]] } 
    #=> [[{:index=>4, :column=>0, :ID=>"ABC", :pet=>"cat"}, 
    #  {:index=>4, :column=>0, :ID=>"ABC", :tree=>"maple"}], 
    # [{:index=>4, :column=>2, :ID=>"BCD-1547", :met=>"Betty"}, 
    #  {:index=>4, :column=>2, :ID=>"BCD-1547", :car=>"beemer"}]] 
+0

謝謝Cary。但是我無法理解什麼類型的數據結構'h1,h2'和'(h1.keys&h2.keys)。map {| k | [h1 [k],h2 [k]]}是。它看起來像h1和h2是散列,而第三個是一個數組數組。你能證實這一點嗎? – danynl

+0

'h1'和'h2'確實是散列,其鍵也是散列。因此'h1.keys'和'h2.keys'是散列的數組,它們的交集是這些散列的數組,它們都是'h1'和'h2'中的鍵。因此我所做的就是創建一個散列在'new_array1'和'new_array2'中爲每個散列關注三個關鍵點,並獲得它們的交集,就像我在所有散列具有相同的三個鍵而沒有其他三個鍵時的情況一樣。最後一步是使用該交點與'h1'和'h2'一起獲得所需的結果。 –

+0

謝謝,我在這裏遇到了另一個問題,如果你能看看,將不勝感激 http://stackoverflow.com/questions/39868693/ruby-array-error-typeerror-cant-convert-symbol-into -integer – danynl