这两个陈述给出了相同的结果:
[1,2,3,4].find_all { |x| x.even? }
[1,2,3,4].select{ |x| x.even? }
find_all
只是一个别名吗?是否有理由使用另一个?
答案 0 :(得分:61)
#find_all
和#select
非常相似;差异非常微妙。在大多数情况下,它们是等价的。这取决于实现它的类。
Enumerable#find_all
和Enumerable#select
运行相同的代码。
Array
和Range
也是如此,因为它们使用Enumerable
实现。
对于Hash
,#select
被重新定义为返回哈希而不是数组,但#find_all
继承自Enumerable
a = [1, 2, 3, 4, 5, 6]
h = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}
a.select{|x| x.even?} # => [2, 4, 6]
a.find_all{|x| x.even?} # => [2, 4, 6]
h.select{|k,v| v.even?} # => {:b=>2, :d=>4, :f=>6}
h.find_all{|k,v| v.even?} # => [[:b, 2], [:d, 4], [:f, 6]]
答案 1 :(得分:16)
Enumerable#find_all
返回一个数组,其中包含给定块返回真值的枚举的所有元素,而select
不是这种情况。 Enumerable#select
会返回Array
,如果您正在调用的接收方为#select
方法,则不会拥有自己的#select
方法。否则,在您调用#select
方法的接收器上,它将在处理块条件后返回相似类型的接收器。
Like Hash#select
返回一个新的哈希,该哈希由块返回的条目true
和Array#select
返回一个包含所有元素的新数组给定块返回真值的ary。现在Range#select
将返回Array
,因为Range
类没有自己的实例方法{{ {1}}。而不是#select
,它会调用Enumerable#select
。
Enumerable
这是一个完整的演示,示例有利于我上面的解释:
rng = (1..4)
ary = [1,2]
hsh = {:a => 1}
rng.method(:select) # => #<Method: Range(Enumerable)#select>
hsh.method(:select) # => #<Method: Hash#select>
ary.method(:select) # => #<Method: Array#select>
答案 2 :(得分:8)