We’re at lucky number 13 — the thirteenth article in the Enumerating Enumerable series, which covers the methods of Ruby’s Enumerable
module. I started this series after being disappointed with the documentation at Ruby-Doc.org.
In this article, I’m covering the find_all
— a.k.a. select
— method.
In case you missed any of the previous articles, they’re listed and linked below:
- all?
- any?
- collect / map
- count
- cycle
- detect / find
- drop
- drop_while
- each_cons
- each_slice
- each_with_index
- entries / to_a
Enumerable#find_all / Enumerable#select Quick Summary
In the simplest possible terms | Which items in the collection meet the given criteria? |
---|---|
Ruby version | 1.8 and 1.9 |
Expects | A block containing the criteria. |
Returns | An array containing the items in the collection that meet the given criteria. If no items in the collection meet the given criteria, this is an empty array. |
RubyDoc.org’s entry | Enumerable#find_all / Enumerable#select |
Enumerable#find_all / Enumerable#select and Arrays
When used on an array, find_all
and its synonym select
passes each item from the array to the block, returning an array containing only those elements in the original array for which the block returns a value that doesn’t evaluate to false
.
If no item in the array causes the block to return a value that doesn’t evaluate to false, find_all
/select
returns an empty array.
In the examples that follow (which are based on my examples for the detect
/find
method), I’ll be using the find_all
method. select
does exactly the same thing; it’s just that I prefer find_all
.
# Once again, I shall establish my "old fart" credentials classic_rock_bands = ["AC/DC", "Black Sabbath", "Queen", \ "Ted Nugent and the Amboy Dukes", "Scorpions", "Van Halen"] => ["AC/DC", "Black Sabbath", "Queen", "Ted Nugent and the Amboy Dukes", "Scorpions", "Van Halen"] # Of the bands in the array, which ones have # a name longer than 8 characters? classic_rock_bands.find_all {|band| band.length > 8} => ["Black Sabbath", "Ted Nugent and the Amboy Dukes", "Scorpions", "Van Halen"] # Which ones have a name exactly 5 characters long? classic_rock_bands.find_all {|band| band.length == 5} => ["AC/DC", "Queen"] # If no band in the array meets the criteria, # find_all returns an empty array. # Which ones have names shorter than 5 characters? classic_rock_bands.find_all {|band| band.length < 5} => []
Enumerable#find_all / Enumerable#select and Hashes
When used on a hash, find_all
/select
passes each key/value pair in the hash to the block, which you can “catch” as either:
- A two-element array, with the key as element 0 and its corresponding value as element 1, or
- Two separate items, with the key as the first item and its corresponding value as the second item.
As with arrays, find_all
/select
passes each item from the hash to the block, returning an array containing only those items in the original array for which the block returns a value that doesn’t evaluate to false
.
Note that each item in the result array is a two-element array corresponding to an item from the original hash. In this array, element 0 contains the key and element 1 contains the corresponding value.
If no item in the hash causes the block to return a value that doesn’t evaluate to false, find_all/select returns an empty array.
years_founded = {"AC/DC" => 1973, \ "Black Sabbath" => 1968, \ "Queen" => 1970, \ "Ted Nugent and the Amboy Dukes" => 1967, \ "Scorpions" => 1965, \ "Van Halen" => 1972} => {"AC/DC"=>1973, "Black Sabbath"=>1968, "Queen"=>1970, "Ted Nugent and the Amboy Dukes"=>1967, "Scorpions"=>1965, "Van Halen"=>1972} # Ruby 1.9 preserves hash order so that hashes keep the order in which # you defined them, while Ruby 1.8 puts them in some mysterious order. # All these examples are in Ruby 1.9 # Which bands were founded in 1970 or later? years_founded.find_all {|band| band[1] >= 1970} => [["AC/DC", 1973], ["Queen", 1970], ["Van Halen", 1972]] # Here's another way of phrasing it: years_founded.find_all {|band, year_founded| year_founded >= 1970} => [["AC/DC", 1973], ["Queen", 1970], ["Van Halen", 1972]] # Which bands were founded after 1980? years_founded.find_all {|band, year_founded| year_founded > 1980} => []
One reply on “Enumerating Enumerable: Enumerable#find_all / Enumerable#select”
[…] actually written a whole series of articles on the power of Ruby’s Enumerable module, including the select method (and what I think was a pretty clever explanation of […]