我无法找到确定散列中是否存在键值对的方法。
h4 = { "a" => 1, "d" => 2, "f" => 35 }
我可以使用Hash#has_value?
和Hash#has_key?
分别查找有关某个键或值的信息,但如何检查是否存在一对?
我之后的Psuedo代码:
if h4.contains_pair?("a", 1)
答案 0 :(得分:4)
请使用:
h4['a'] == 1
对我来说似乎太过分了,但你可以用这样的方法修补Hash:
class Hash
def contains_pair?(key, value)
key?(key) && self[key] == value
end
end
答案 1 :(得分:1)
我承认开始一条路,然后想知道它可能会带我去哪里。这可能不是确定哈希中是否存在键/值对的最佳方法(如何改进@ 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
<强>讨论强>
我们当然可以将哈希值转换为数组,然后应用Array#include?:
h.to_a.include?(['a', 1])
#=> true
但这有创建临时数组的缺点。如果类Hash
具有这样的实例方法会很好,但事实并非如此。有人可能认为可能会使用Hash#include?,但它只需要一个参数,一个键。 1 。
方法Enumerable#include?执行我们想要的操作,当然Hash
include
执行Enumerable
模块。我们可以通过各种方式调用该方法。
将Enumerable#include?
绑定到哈希并将其命名为
这当然是我的答案:
Enumerable.instance_method(:include?).bind(h).call([k,v])
使用v2.2中介绍的方法Method#super_method。
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?>
执行alias_method
/ remove_method
旋转木马
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)
将哈希转换为枚举器并调用Enumerable#include?
h.to_enum.include?(['a',1])
#=> true
h.to_enum.include?(['a',2])
#=> false
这是有效的,因为课程Enumerator也include
s Enumerable
。
1 Hash#include?
与Hash#key?和Hash#has_key?相同。这让我想知道为什么include?
不能用于本目的,因为确定散列是否具有给定的密钥是很好的。
答案 2 :(得分:0)
如何使用Enumerable any?
h4 = { "a" => 1, "d" => 2, "f" => 35 }
h4.any? {|k,v| k == 'a' && v == 1 }