2013-12-11 55 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"}}