documentation for Enumerable#find
/#detect
说:
find(ifnone = nil) { |obj| block } → obj or nil
find(ifnone = nil) → an_enumerator
将 enum 中的每个条目传递给块。 返回哪个块的第一个 不是假的。如果没有对象匹配,则调用 ifnone 并返回它 指定时的结果,否则返回
nil
。
但是,当在Hash上调用它时,结果将类型更改为Array而不是原始Hash。
是否存在某些实现错误或有关此数据类型的一些历史约定?
{a: 'a', b:'b'}.find {|k, v| v == 'b'}
# => [:b, 'b']
答案 0 :(得分:5)
Hash#detect
继承自Enumerable#detect
方法。
Enumerable
模块基于sort
方法生成多个方法(例如min
,max
,detect
,包括each
等)该课程包括Enumerable
。
它不关心each
的实施方式,只要它
“......产生该系列的连续成员。” 来自ruby-doc
因此对于Hash#detect
方法,它依赖于Hash#each
的行为,即:
为hsh中的每个键调用一次阻塞,将键值对传递为 参数。如果没有给出块,则返回枚举器。
h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }
因为Hash#each
将哈希产生为两对数组,所以从Enumerable
模块继承的所有方法都基于此工作。
这就是Hash#detect
生成两个元素数组而不是散列对象本身的原因。
答案 1 :(得分:4)
find
是根据each
实施的。并且each
在Hash上调用时,以数组的形式返回键值对,每个元素包含2个元素。这就是find
返回数组的原因。
答案 2 :(得分:0)
使用带有哈希的检测/查找
使用哈希,detect / find将散列中的每个键/值对传递给块,您可以将其“捕获”为:
一个双元素数组,键为元素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”