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

时间:2016-03-15 00:04:12

标签: ruby hash key-value

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

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

我可以使用Hash#has_value?Hash#has_key?分别查找有关某个键或值的信息,但如何检查是否存在一对?

我之后的Psuedo代码:

if h4.contains_pair?("a", 1)

3 个答案:

答案 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

这是有效的,因为课程Enumeratorinclude 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 }