Understanding Map and Reduce in Ruby

I frequently google a problem I’m solving to find better ways to write a given line of code. One common type of one-liner uses the map and reduce functions.

Today, I came across a one liner to sum the digits of an integer:

n.to_s.chars.map(&:to_i).reduce(:+)

bitops/digit_sum.rb

When I was starting out, I found these one-liners too dense to wrap my mind around. I wanted to write out a quick primer for new developers looking to understand how Map and Reduce work.

Map and Reduce are two great functions that function great together.

Map

Map takes an enumerable and applies a function or set of commands to each element, then returns a new array with the updated elements. (Note: If you want to modify the original array with map, you can use map!).

Lets look at a couple of examples where we passs a function to map:

irb> [1,2,3,4,5].map(&:to_f)
=> [1.0, 2.0, 3.0, 4.0, 5.0]

irb> '135'.chars.map(&:to_i)
=> [1, 3, 5]

Map also works where we define our own process to run on each value:

irb> [1,2,3,4,5].map{ |m| m + 1 }
=> [2, 3, 4, 5, 6]

irb> '135'.chars.map{ |m| m + ' unit' }
=> ["1 unit", "3 unit", "5 unit"]

Here’s a quick example of map!

irb> a = [1,3,5]
=> [1, 3, 5]
irb> a.map!{|m| m + 1 }
=> [2, 4, 6]
irb> a
=> [2, 4, 6]

So now we can take an array and perform functions on it’s values quickly.

Reduce

With Reduce, we combine all elements of an enumerable. Similar to map, we can pass a function, or define a process of our own. However, there is no reduce! function.

Here are a couple simple examples:

irb> [1,2,3,4].reduce(:+)
=> 10

irb> [1,2,3,4].reduce(:*)
=> 24

We can pass our own reduce funciton. Remember, it takes two arguments, the

irb> ['a','b','c'].reduce { |reduced, n| reduced + n }
=> "abc"

irb> ['a','b','c'].reduce { |reduced, n| n + reduced }
=> "cba"

Map and Reduce

Now that you understand the one-liner I showed at the top of the page?

n.to_s.chars.map(&:to_i).reduce(:+)

This has been an overview of Map and Reduce in Ruby, but once you understand how to use the concept, you’ll find yourself using them in most languages.