比较除了密钥之外的ruby中的两个哈希数组

时间:2013-12-11 07:37:13

标签: ruby hash

我有两个这样的哈希数组:

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

但这似乎是不正确的。有没有人有更好的解决方案。我在普通的ruby 1.9.3上,没有使用rails框架。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

如果hash1.length != hash2.length,那么你可以立即纾困,因为它们不能相同。如果他们有相同的长度,那么你可以做这样的事情:

except_id = ->(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方式,可以在没有特定键的情况下非破坏性地查看Hash。你也可以使用:

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)

答案 2 :(得分:0)

问题不一定清楚,但我认为考虑了哈希的顺序。

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