ruby 为什么即使在哈希函数上调用,ESPRIT #find/#detect也会返回一个数组?

7d7tgy0s  于 12个月前  发布在  Ruby
关注(0)|答案(4)|浏览(90)

Enumerable#find/#detect的文档说:

find(ifnone = nil) { |obj| block } → obj or nil

find(ifnone = nil) → an_enumerator
enum 中的每个条目传递给 block。**返回第一个不为false的block。如果没有对象匹配,则调用 ifnone 并在指定时返回其结果,否则返回nil
但是,当在Hash上调用它时,结果将类型更改为Array而不是原始Hash。
这是一些实现错误还是关于这个数据类型的一些历史约定?

{a: 'a', b:'b'}.find {|k, v| v == 'b'}
# => [:b, 'b']
vlju58qv

vlju58qv1#

Hash#detect继承自Enumerable#detect方法。
Enumerable模块基于包含Enumerable的类的each方法生成多个方法(如sortminmax包括detect等)。
它并不关心each是如何实现的,只要它
“.产生集合的连续成员。“从ruby-doc
所以对于Hash#detect方法,它依赖于Hash#each的行为,即:
对hsh中的每个键调用一次block,并将键值对作为参数传递。如果没有给出块,则返回枚举数。

h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }

因为Hash#each以两对数组的形式产生哈希,所以从Enumerable模块继承的所有方法都基于此工作。
这就是为什么Hash#detect生成一个两个元素的数组,而不是哈希对象本身。

iq0todco

iq0todco2#

find是根据each实现的。而each,当在Hash上调用时,以数组的形式返回键值对,每个键值对有2个元素。这就是为什么find返回一个数组。

dgenwo3n

dgenwo3n3#

  • 使用检测/查找哈希 *

使用hash,detect/find将hash中的每个键/值对传递给块,您可以“捕获”为:

  • 一个两个元素的数组,键为元素0,对应的值为元素1,* 或
h = {:a => 'a', :b => 'b'}
p h.find {|k| p k ; k[1] == 'b'}
  • 输出:*
[:a, "a"]
[:b, "b"]
[:b, "b"]
  • 两个单独的项,键作为第一项,其对应的值作为第二项。*
h = {:a => 'a', :b => 'b'}
p h.find {|k, v| puts k,v ; v == 'b'}
  • 输出:*
a
a
b
b
[:b, "b"]

要了解更多关于此主题的信息,请查看此处Enumerating Ruby’s “Enumerable” Module, Part 3: “detect”, a.k.a. “find”Enumerating Ruby’s “Enumerable” Module, Part 3: “detect”, a.k.a. “find”

wswtfjt7

wswtfjt74#

我可以用这个:

h = { "a" => 100, "b" => 200 }.keys.include?("a") # for key

h = { "a" => 100, "b" => 200 }.values.include?(100) # for value

相关问题