Ruby 检测散列中是否存在键值对

Ruby 检测散列中是否存在键值对,ruby,hash,key-value,Ruby,Hash,Key Value,我找不到确定散列中是否存在键值对的方法 h4 = { "a" => 1, "d" => 2, "f" => 35 } 我可以使用Hash#has_value?和Hash#has_key?分别查找有关键或值的信息,但如何检查是否存在一对 我要找的东西的Psuedo代码: if h4.contains_pair?("a", 1) 只要用这个: h4['a'] == 1 对我来说,这似乎太过分了,但您可以使用如下方法进行monkey patch Hash: class Hash

我找不到确定散列中是否存在键值对的方法

h4 = { "a" => 1, "d" => 2, "f" => 35 }
我可以使用
Hash#has_value?
Hash#has_key?
分别查找有关键或值的信息,但如何检查是否存在一对

我要找的东西的Psuedo代码:

if h4.contains_pair?("a", 1)
只要用这个:

h4['a'] == 1
对我来说,这似乎太过分了,但您可以使用如下方法进行monkey patch Hash:

class Hash
  def contains_pair?(key, value)
    key?(key) && self[key] == value
  end
end

使用Enumerable怎么样


我承认我开始沿着一条路走,然后想知道它会把我带到哪里。这可能不是确定散列中是否存在键/值对的最佳方法(如何改进@Jordan的答案?),但我在这一过程中学到了一些东西

代码

def pair_present?(h,k,v)
  Enumerable.instance_method(:include?).bind(h).call([k,v])
end
示例

h = { "a"=>1, "d"=>2, "f"=>35 }

pair_present?(h,'a',1)
  #=> true

pair_present?(h,'f',36)
  #=> false

pair_present?(h,'hippopotamus',2)
  #=> false
讨论

我们当然可以将散列转换为数组,然后应用:

但这也有创建临时数组的缺点。如果类
Hash
有这样一个实例方法就好了,但是它没有。有人可能会认为它可能用于此,但它只需要一个参数,一个键

这个方法做了我们想要的,当然
散列
包括
可枚举的
模块。我们可以以各种方式调用该方法

Enumerable#include?
绑定到散列并调用它

这当然是我的回答:

Enumerable.instance_method(:include?).bind(h).call([k,v])
使用v2.2中介绍的方法

h.method(:include?).super_method.call(['a',1])
  #=> true
h.method(:include?).super_method.call(['a',2])
  #=> false
请注意:

h.method(:include?).super_method
  #=> #<Method: Object(Enumerable)#include?>
将哈希转换为枚举数并调用
Enumerable#include?

这是因为类也
包含
s
可枚举


1
Hash#include?
与and相同。这让我想知道为什么
include?
没有用于目前的目的,因为确定哈希是否具有给定的键是很好的覆盖

该值是否可能为
nil
?感谢您的注释sawa!Jordan已经解决了这两种情况。唉,我以为你只能用这种语法设置哈希值——没有想到尝试
==
。我希望你没有看到这条线Jordan。。。现在你知道我真的是个笨蛋了。我很快会把你的答案标记为正确的,因为它是最简洁的。乔丹,你有机会看一眼漂亮的吗?我在一个对我来说很重要的项目上碰壁了,到目前为止,几天后我对此没有任何反应。当我们可以在O(1)时间内直接访问密钥时,迭代整个哈希似乎有点奇怪。哇,好东西。我很高兴我问了这个问题,而不是回避它,因为我觉得它太简单了。这真是好东西,谢谢Cary!
h.method(:include?).super_method.call(['a',1])
  #=> true
h.method(:include?).super_method.call(['a',2])
  #=> false
h.method(:include?).super_method
  #=> #<Method: Object(Enumerable)#include?>
Hash.send(:alias_method, :temp, :include?)
Hash.send(:remove_method, :include?)
h.include?(['a',1])
  #=> true
h.include?(['a',2])
  #=> false
Hash.send(:alias_method, :include?, :temp)
Hash.send(:remove_method, :temp)
h.to_enum.include?(['a',1])
  #=> true
h.to_enum.include?(['a',2])
  #=> false