9

/文档Enumerable#find#detect说:

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

将enum中的每个条目传递给block返回第一个不为假的块。如果没有对象匹配,则调用ifnone并在指定时返回其结果,否则返回nil

但是,当它在 Hash 上调用时,结果已经将类型更改为 Array 而不是原来的 Hash。

是关于这个数据类型的一些实现错误还是一些历史约定?

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

3 回答 3

6

Hash#detect继承自方法Enumerable#detect

Enumerable模块根据包含的类的方法生成多个方法(如sort、、包含min等)。maxdetecteachEnumerable

它不关心如何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生成一个二元素数组而不是哈希对象本身的原因。

于 2013-05-18T18:00:40.413 回答
4

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

于 2013-04-27T10:06:29.917 回答
0
于 2013-04-27T10:25:35.693 回答