Reputation: 10243
These two statements give me the same results:
[1,2,3,4].find_all { |x| x.even? }
[1,2,3,4].select{ |x| x.even? }
Is find_all
just an alias? Is there a reason to use one over another?
Upvotes: 35
Views: 22510
Reputation: 1
with array it returns result as array
with hash it returns result as array
with array it returns result as array
with hash it returns result as hash
Upvotes: -1
Reputation: 118289
Enumerable#find_all
Returns an array containing all elements of enum for which the given block returns a true value, which is not the case for select
. Enumerable#select
returns the Array
, if the receiver on which you are calling #select
method, don't have it's own #select
method. Otherwise on which receiver you are calling #select
method, it will return similar type of receiver, after processing the block condition.
Like Hash#select
Returns a new hash consisting of entries for which the block returns true
and Array#select
Returns a new array containing all elements of ary for which the given block returns a true value. Now Range#select
will give you return back an Array
, as Range
class don't have its own instance method called #select
. Rather being an Enumerable
,it will call Enumerable#select
.
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>
Here is a full demonstration with example in-favor of my explanation above :
hsh = {:a => 2, :b => 3 }
ary = [1,2,3]
rng = (1..3)
# Look find_all always gives Array.
hsh.find_all{ true } # => [[:a, 2], [:b, 3]]
ary.find_all{ true } # => [1, 2, 3]
rng.find_all{ true } # => [1, 2, 3]
# Look select not giving Array always, explanation of why so is written
# above in my answer.
hsh.select{ true } # => {:a=>2, :b=>3}
ary.select{ true } # => [1, 2, 3]
rng.select{ true } # => [1, 2, 3]
Upvotes: 16
Reputation: 124439
Yes, for Arrays, they return identical results. For other things (e.g. Hashes), they may return different things.
According to the Enumerable documentation for select and find_all, both methods point to the same source code, and both return either an Array (if a block is given) or an Enumerator (if no block is given).
While the Array class implements its own version of select
(but lets Enumerable handle find_all
), they still do the same thing.
Upvotes: 8
Reputation: 3424
#find_all
and #select
are very similar; the difference is very subtle. In most of the cases, they are equivalent. It depends on the class implementing it.
Enumerable#find_all
and Enumerable#select
run on the same code.
The same happens for Array
and Range
, as they use Enumerable
implementation.
In the case of Hash
, #select
is redefined to return a Hash instead of an Array, but #find_all
is inherited from 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]]
Upvotes: 69