如何检查一个哈希在另一个哈希中是否“完全”包含?

24
我正在使用Ruby on Rails 3.1.0,我想检查一个哈希是否“完全”包含在另一个哈希中,并返回一个布尔值。
假设我有这些哈希:
hash1 = {
  :key1 => 'value1',
  :key2 => 'value2',
  :key3 => 'value3'
}

hash2 = {
  :key1 => 'value1',
  :key2 => 'value2',
  :key3 => 'value3',
  :key4 => 'value4',
  :key5 => 'value5',
  ...
}
我想检查hash1是否包含在hash2中,即使hash2中有比hash1更多的值(在上面的情况下,我要寻找的响应应该是true)。是否可能通过使用“仅一个代码行”或“一个 Ruby 方法”来实现?

1
也许你可以将hash1合并到hash2中(hash2.merge(hash1)),然后查看是否有变化。这是一种非常朴素的方法,但如果你只想要一行代码,那么这可能是最简单的方法。 - user824425
7个回答

45

那就足够了

(hash1.to_a - hash2.to_a).empty?

好的。这就是为什么我在我的回答中加入了“我能想到的”这部分的原因;-) - Michael Kohl
太棒了!我刚刚花了一个小时玩 collect include? values_at 等等... 没有任何合理的结果。最终找到了这个答案。如此简单。 - Kocur4d

5

更加优雅的方法是在合并哈希表时检查相等性。

例如,需要重新编写Hash的include?实例方法以实现此功能。

class Hash
  def include?(other)
    self.merge(other) == self
  end
end

{:a => 1, :b => 2, :c => 3}.include? :a => 1, :b => 2 # => true

5
我能想到的最简单的方法是:
hash2.values_at(*hash1.keys) == hash1.values

3

有一种方法:

hash_2 >= hash_1

或者:

hash_1 <= hash_2

这篇文章提供了更好的Ruby哈希表实现方案,点击此处查看更多信息。


1
自从Ruby 2.3版本以来,你可以这样做:
hash1 <= hash2

1
我找到的最有效和优雅的解决方案 - 没有中间数组或冗余循环。
class Hash
  alias_method :include_key?, :include?

  def include?(other)
    return include_key?(other) unless other.is_a?(Hash)
    other.all? do |key, value|
      self[key] == value
    end
  end
end

自 Ruby 2.3 版本以来,您可以使用内置的Hash#<= 方法。

0

我不确定我是否理解哈希表中包含的概念。 为了查看它是否具有相同的键(通常的问题)。 哈希表1中的所有键都包含在哈希表2中: hash1.keys - hash2.keys == []

然后,如果您想要比较这些值,请按照先前的帖子建议执行以下操作: hash1.values - hash2.values_at(*hash1.keys) == []


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接