In the last article in this series covering the methods in Ruby’s Enumerable
module, I covered all?
and any?
. In this installment, I’ll look at the collect
method, a.k.a. the map
method.
collect, a.k.a. map
- In plain language: Create an array by performing some operation on every item in the given collection.
- Ruby.Doc.org’s entry:
Enumerable#collect
/Enumerable#map
- Expects: A block containing the operation (it’s optional, but you’re likely to use one most of the time).
- Returns: An array made up of items created by performing some operation on the given collection.
collect
and map
are synonyms — you can use either. I personally prefer map
as it’s shorter and makes more sense: I view the operation as using a function to map a collection to an array.
Using collect
/map
with Arrays
When used on an array and a block is provided, collect
/map
passes each item to the block, where the operation in the block is performed on the item and the result is then added to the result array. Note the the result array has the same number of elements as the given array.
[1, 2, 3, 4].map {|number| number ** 2} => [1, 4, 9, 16] ["Aqua", "Bat", "Super", "Wonder Wo"].map {|adjective| adjective + "man"} => ["Aquaman", "Batman", "Superman", "Wonder Woman"]
When the block is omitted, collect
/map
uses this implied block: {|item| item}
, which means when applied on an array without a block, collect
/map
is the identity function — the resulting array is the same as the given array.
[1, 2, 3, 4].map => [1, 2, 3, 4] ["Aqua", "Bat", "Super", "Wonder Wo"].map => ["Aqua", "Bat", "Super", "Wonder Wo"]
Using collect
/map
with Hashes
When used on a hash and a block is provided, collect
/map
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.
Each key/value pair is passed to the block, where the operation in the block is performed on the item and the result is then added to the result array. Note the the result array has the same number of elements as the given array.
burgers = {"Big Mac" => 300, "Whopper with cheese" => 450, "Wendy's Double with cheese" => 320} # What if I had just half a burger? burgers.map {|burger| burger[1] / 2} => [160, 150, 225] burgers.map {|sandwich, calories| calories / 2} => [160, 150, 225] burgers.map {|burger| "Have a tasty #{burger[0]}!"} => ["Have a tasty Wendy's Double with cheese!", "Have a tasty Big Mac!", "Have a tasty Whopper with cheese!"] burgers.map {|sandwich, calories| "Have a tasty #{sandwich}!"} => ["Have a tasty Wendy's Double with cheese!", "Have a tasty Big Mac!", "Have a tasty Whopper with cheese!"] burgers.map {|sandwich, calories| ["Half a #{sandwich}", calories / 2]} => [["Half a Wendy's Double with cheese", 160], ["Half a Big Mac", 150], ["Half a Whopper with cheese", 225]]
When the block is omitted, collect
/map
uses this implied block: {|item| item}
, which means when applied on an hash without a block, collect
/map
returns an array containing a set of two-item arrays, one for each key/value pair in the hash. For each two-item array, item 0 is the key and item 1 is the corresponding value.
burgers = {"Big Mac" => 300, "Whopper with cheese" => 450, "Wendy's Double with cheese" => 320} burgers.map => [["Wendy's Double with cheese", 320], ["Big Mac", 300], ["Whopper with cheese", 450]]
Special Case: Using collect
/map
on Empty Arrays and Hashes
When applied to an empty array or hash, with or without a block, all?
always returns true
.
[].map => [] [].map {|item| item * 2} => [] {}.map => [] {}.map {|sandwich, calories| "Have a tasty #{sandwich}!"} => []
In the Next Installment…
…the detect
(a.k.a. find
) method.
One reply on “Enumerating Ruby’s “Enumerable” Module, Part 2: “collect”, a.k.a. “map””
Great series! Just a note on a type, probably a carryover from the first post:
You have:
Special Case: Using collect/map on Empty Arrays and Hashes
When applied to an empty array or hash, with or without a block, all? always returns true.
I think you mean to say:
Special Case: Using collect/map on Empty Arrays and Hashes
When applied to an empty array or hash, with or without a block, map always returns an empty array.