Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "find_all" and "select" the same thing?

Tags:

ruby

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?

like image 891
ek_ny Avatar asked Jan 08 '14 15:01

ek_ny


People also ask

What is soup select in Python?

Beautiful Soup provides the . select() method which is used to run a CSS selector against a parsed document and return all the matching elements. Beautiful Soup (bs4) is the python package that is used to scrape the data from web pages.

What is select in Ruby?

Array#select() : select() is a Array class method which returns a new array containing all elements of array for which the given block returns a true value. Syntax: Array.select() Parameter: Array. Return: A new array containing all elements of array for which the given block returns a true value.


2 Answers

#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]] 
like image 98
wacko Avatar answered Sep 30 '22 15:09

wacko


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] 
like image 32
Arup Rakshit Avatar answered Sep 30 '22 13:09

Arup Rakshit