2013-12-11 57 views
1

我有兩個哈希數組是這樣的:比較紅寶石兩個哈希陣列,除了一鍵

hashArray1 = [{"id"=>"1","data"=>"data1"},{"id"=>"2","data"=>"data2"}] 
hashArray2 = [{"id"=>"3","data"=>"data1"},{"id"=>"4","data"=>"data2"}] 

我想比較兩者,如果一切沒有「ID」鍵匹配返回true。

我已經試過這樣的事情:

hashArray1.each do |h1| 
    hashArray2.each do |h2| 
    if h1.select{|h| h!= "id"} == h2.select{|b| b!= "id"} 
     break 
    else 
     return false 
    end 
    end 
end 

但這似乎是不正確的。有沒有人有更好的解決方案。我在1.9.3平原紅寶石,不使用rails框架。

+1

您的變量名稱'hash1'和'hash2'具有誤導性。他們不是哈希。 – sawa

+0

@sawa點指出,現在希望它罰款。但這個問題已經得到解答。 –

回答

2

我只想做:

hash1.zip(hash2).all? do |h1,h2| 
    return false unless h1.keys == h1.keys 
    h1.keys.each do |key| 
     return false if h1[key] != h2[key] unless key == 'id' 
    end 
end 
2

如果hash1.length != hash2.length那麼你就可以擺脫困境馬上,因爲他們可以是不一樣的。如果它們具有相同的長度,那麼你可以做這樣的事情:

except_id = lambda { |h| h.reject { |k, v| k == 'id' } } 
same = hash1.zip(hash2).find { |h1, h2| except_id[h1] != except_id[h2] }.nil? 

如果sametrue那麼它們是相同的(而忽略'id' S),否則他們是不同的。使用Hash#reject是一種純粹的Ruby方法,可以在無需特定密鑰的情況下非破壞性地查看哈希。您還可以使用:

except_id = lambda { |h| h = h.dup; h.delete('id'); h } 

如果「複製和刪除」對您更有意義而不是篩選。如果你不喜歡find然後all?可能會讀更好:

same = hash1.zip(hash2).all? { |h1, h2| except_id[h1] == except_id[h2] } 

甚至:

same_without_id = lambda { |h1, h2| except_id[h1] == except_id[h2] } 
same == hash1.zip(hash2).all?(&same_without_id) 
+0

我也很喜歡你的回答,但是因爲@hirolau先回答了幾乎同樣的事情,所以接受它,但是對你而言是一個滿意的答案。謝謝.. :) –

+0

這很酷,hirolau也從我這裏得到了讚揚。 –

0

的問題是未必清楚,但我相信散列的順序考慮。

hash1.map{|h| h.reject{|k, _| k == "id"}} == 
hash2.map{|h| h.reject{|k, _| k == "id"}}