If you have bounced back and forth between Ruby and JavaScript like I have, you may have found yourself doing some mathematical operations in Ruby and thinking to yourself, "Wouldn't it be nice if Ruby had a reduce method?". If you followed a similar Ruby learning path to me, you might have learned about the inject
method, but not put two and two together (ha!).
In Ruby, inject
and reduce
are aliases for each other. They both behave the same way, and there is no performance benefit to one over the other. They both combine all elements to a single output. reduce
is a Ruby enumerable, which means that for each element in your argument, something is done. In the case of reduce
, you can specify an operation, a block, or pass in a symbol to tell the reduce method how you want your values, um, reduced.
For example:
def reduce_sum(array)
array.reduce(0) { |sum, num| sum + num }
end
In this method, we are passing in an array of numbers to add up to a total. We pass in 0 as the initial argument to reduce, so it knows where to start counting. Then, inside the block, we tell the reduce
method what we want it to do. For this method, we want the reduce method to keep a running total, called sum
, and then add each number in the array to it. So if we pass in the array [1, 2, 3, 4, 5]
, our operation will look something like this as reduce iterates over the array:
sum = 0
sum = 0 + 1
sum = 1 + 2
sum = 3 + 4
sum = 7 + 5
A shorthand way of writing the same method would be:
def reduce_sum(array)
array.reduce(:+)
end
If you do not tell reduce
what the initial value is, the first element of the array is used as the initial value. Here, we're passing in a symbol instead of a block which tells reduce
to add up all the elements in the array.
You use reduce to do all sorts of mathematical operations on larger amounts of numbers where a final answer is the desired output. Here's an example with multiplication:
def reduce_mult(nums)
nums.reduce(1, :*)
end
Here, we have to tell the reduce
method to start at 1, since 0 * anything is 0, and the method will output 0 every time, no matter what you pass in.
I hope this helps the next time you find yourself needing to do math with more than two numbers in Ruby!
Top comments (1)
I found out about this when I was working on codewars problems. A lot of people were using reduce and I had no idea why. Now I know.