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

问题描述 投票:2回答:3

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

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

我想比较它们两个并返回true如果其他所有匹配没有“id”键。

我试过这样的事情:

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框架。

ruby hash
3个回答
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 = ->(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)

0
投票

问题不一定清楚,但我假设哈希的顺序被考虑在内。

hash1.map{|h| h.reject{|k, _| k == "id"}} ==
hash2.map{|h| h.reject{|k, _| k == "id"}}
© www.soinside.com 2019 - 2024. All rights reserved.