Map, Reduce & Select in Ruby
Mastering Enumerable Methods for Powerful Data Transformation # MapReduceSelectSeries — Episode 0
Introduction
👉Click here to view the full interactive notebook for this episode.
The Ruby library includes the Enumerable module, which provides powerful methods like map, reduce, and select. These functions enable efficient data transformation and manipulation.
By the end of this series, you’ll master breaking data-processing problems into clear, debuggable, and composable stages. This will make your Ruby code more efficient, elegant, and robust.
This tutorial explores common IRB operations, including defining methods, using map , reduce and Select.
Lets Get Started!
Note: if you get stuck, please see my repo Or as Jupyter Notebook.
0.Defining a Simple Function f(x)
def f(x)
x*x
endf(x) returns the square of x.
1.Using MAP for Transformation — The job of map() is to apply
a function or block to each member of the array and return a new array
Applying a Function to an Array
out_array = [1,2,3,4,5].map do |n|
f(n)
end=> [1, 4, 9, 16, 25]Alternatively, using a block:
out_array = [1,2,3,4,5].map { |n| n*n }=> [1, 4, 9, 16, 25]Mapping with Multiple Values
out_array = [1,2,3,4,5].map { |n| [n, n*n] }=> [[1, 1], [2, 4], [3, 9], [4, 16], [5, 25]]Chaining map Calls
out_array = [1,2,3,4,5].map do |n| n*n
end.map do |s| s+100
end=> [101, 104, 109, 116, 125]2.Using REDUCE for Accumulation — The job of reduce() is to apply a function cumulatively to each member of the collection and then return an object (which could be an array, a single value, a hash, or anything)
Summing Elements
[1,2,3,4,5].reduce(0,:+)=> 15reduce Syntax
[1,2,3,4,5].reduce(33) do |memo, elem|
memo.+(elem)
end
=> 48Handling Side Effects in reduce
[1,2,3,4,5].reduce(33) do |memo, elem|
memo.+(elem)
77.7 # Always returns 77.7
end=> 77.7Using reduce with Hashes
[1,2,3,4,5].reduce({}) do |memo, elem|
memo[elem] = elem.to_s
memo
end=> {1=>"1", 2=>"2", 3=>"3", 4=>"4", 5=>"5"}Using reduce for Factorial Calculation
[1,2,3,4,5].reduce(1,:*)=> 120Using reduce to Keep Track of Last Two Elements
ini_memo = [nil, nil]=> [nil, nil]last_2=(1..10).reduce(ini_memo) do |memo, elem|
ini_memo.push(elem)
ini_memo.shift
ini_memo
end
=> [9, 10]Using reduce and select to find the odd numbers of the last five in a sequence
sequence = [1,2,3,455,5,6,4,3,45,66,77,54,23,4,55,6,7]
=> [1, 2, 3, 455, 5, 6, 4, 3, 45, 66, 77, 54, 23, 4, 55, 6, 7]sequence.reduce([nil,nil,nil,nil,nil]) do |memo, n|
memo.push(n)
memo.shift
memo
end.select do |odds_of_last_5|
odds_of_last_5 %2 == 1
end=> [23, 55, 7]This code uses reduce to maintain the last five elements of the sequence and select to filter out the odd numbers from those five elements.
reduceiterates over the sequence, pushing each number into a memo array while maintaining only the last five numbers.selectfilters those last five numbers, returning only the odd ones.
Final output: [23, 55, 7] are the odd numbers from the last five elements of the sequence.
Conclusion
This tutorial covered fundamental IRB operations, including defining methods, using map for transformations, and leveraging reduce for accumulation. By understanding these functions, you can effectively manipulate data and debug errors in Ruby.
Get J3’s stories in your inbox
Join Medium for free to get updates from this writer.
Happy coding! 🚀
Credits & references
Book: Ruby Data Processing — Using Map, Reduce, and Select by Jay Godse
Note 0 : Difference Between pluck and map
.map { |user| user['email'] } is pure Ruby and works on any array of hashes.
.pluck('email') is optimized in Rails and can be used on ActiveRecord queries for better performance.
Example in ActiveRecord
User.pluck(:email) # Fetches emails directly from the databaseThis is much faster than:
User.all.map { |user| user.email }because pluck only loads the requested column, while map loads entire objects.
When to Use pluck?
When working with ActiveRecord models in Rails.
When extracting values from large datasets for better performance.
Note 2: More reduce() Examples:
Here are several practical examples of using reduce in Ruby with brief explanations:
- Product of all elements
[1, 2, 3, 4, 5].reduce(1, :*)
# => 120Explanation:
Starts with 1, multiplies each element → 1*2*3*4*5 = 120.
2. Concatenate strings
["Hello", " ", "World", "!"].reduce("", :+)
# => "Hello World!"Explanation:
Starts with an empty string “” and concatenates each part.
3. Find the maximum number
[3, 7, 2, 9, 4].reduce { |max, n| max > n ? max : n }
# => 9Explanation:
No initial value needed. Compares each pair to keep the highest.
4. Flatten nested arrays
[[1, 2], [3, 4], [5]].reduce([], :+)
# => [1, 2, 3, 4, 5]Explanation:
Starts with an empty array [] and concatenates subarrays.
5. Build a hash from an array
["apple", "banana", "cherry"].reduce({}) do |hash, fruit|
hash[fruit] = fruit.length
hash
end
# => {"apple"=>5, "banana"=>6, "cherry"=>6}Explanation:
Starts with an empty hash, and for each fruit, stores its length.
6. Sum only even numbers
[1, 2, 3, 4, 5, 6].reduce(0) do |sum, n|
n.even? ? sum + n : sum
end
# => 12Explanation:
Only adds 2 + 4 + 6.
Note 1 — Ruby 3 shorthand Syntax
Both the classic syntax and the Ruby 3 shorthand are shown here — along with a look at whether the shorthand truly adds any benefit in this case.
🧱 Classic way
out_array = [1, 2, 3, 4, 5].map { |n| [n, n * n] }Result:
[[1, 1], [2, 4], [3, 9], [4, 16], [5, 25]]🪄 Ruby 3 shorthand
out_array = [1, 2, 3, 4, 5].map { [_1, _1 * _1] }✅ Works exactly the same — because _1 represents the single block argument (n).
⚖️ Readability trade-off
In this example, the classic form:
|n| [n, n * n]is more readable because n conveys intent — you’re mapping over numbers.
The shorthand:
[_1, _1 * _1]is okay for one-liners in functional code, but a bit opaque for everyday Rails or scripting work.









