Enumerable#reduce
enum.reduce(initial) { |acc, elem| } Object · Added in v1.8.7 · Updated March 16, 2026 · Enumerable The reduce method (also known as inject or fold in other programming languages) accumulates values by applying a binary operation to each element, carrying the result forward until the entire collection is reduced to a single value.
This method is essential for tasks like summing numbers, building strings, finding maximum values, or any operation that combines all elements into one result.
Basic Usage
The simplest form of reduce accumulates all elements using a starting value:
numbers = [1, 2, 3, 4, 5]
sum = numbers.reduce(0) { |acc, num| acc + num }
# => 15
The block receives two parameters: the accumulator and the current element. The return value of the block becomes the new accumulator for the next iteration.
Shorthand Symbol Syntax
Ruby provides a convenient shorthand when the operation is a simple method call:
numbers = [1, 2, 3, 4, 5]
sum = numbers.reduce(:+)
# => 15
This is equivalent to the block version but more concise. You can use any binary method name as a symbol.
Without Initial Value
If you omit the initial value, reduce uses the first element as the starting accumulator:
numbers = [1, 2, 3, 4, 5]
sum = numbers.reduce { |acc, num| acc + num }
# => 15
Ruby starts with element 1 as the accumulator and then processes elements 2 through 5.
Caution: With an empty collection and no initial value, reduce returns nil:
[].reduce { |acc, x| acc + x }
# => nil
Common Examples
Summing Numbers
prices = [10, 20, 30, 40]
total = prices.reduce(0, :+)
# => 100
Finding Maximum Value
scores = [45, 87, 23, 92, 55]
highest = scores.reduce { |max, score| score > max ? score : max }
# => 92
Building a String
words = ["Hello", "World", "from", "Ruby"]
sentence = words.reduce("") { |str, word| str + word + " " }
# => "Hello World from Ruby "
Flattening Nested Arrays
matrix = [[1, 2], [3, 4], [5, 6]]
flat = matrix.reduce([]) { |acc, arr| acc + arr }
# => [1, 2, 3, 4, 5, 6]
Creating a Hash from Arrays
keys = [:a, :b, :c]
values = [1, 2, 3]
hash = keys.zip(values).reduce({}) { |h, (k, v)| h.merge(k => v) }
# => { a: 1, b: 2, c: 3 }
The inject Alias
inject is an alias for reduce — they behave identically:
[1, 2, 3].reduce(0, :+)
# => 6
[1, 2, 3].inject(0, :+)
# => 6
Many developers prefer reduce because the name more intuitively describes what happens.
Practical Patterns
Factorial Calculation
def factorial(n)
(1..n).reduce(1, :*)
end
factorial(5)
# => 120
Chaining Transformations
result = [1, 2, 3, 4, 5]
.reduce([]) { |acc, x| acc << x * 2 }
.reduce(0, :+)
# => 30
Grouping by Attribute
people = [
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Carol", age: 30 }
]
grouped = people.reduce({}) do |acc, person|
age = person[:age]
acc[age] ||= []
acc[age] << person[:name]
acc
end
# => { 30 => ["Alice", "Carol"], 25 => ["Bob"] }
Performance Notes
reduce is efficient and lazy in the sense that it does not create intermediate collections when using the symbol shorthand. However, for simple sums, specialized methods like sum may be more readable:
# Using reduce
[1, 2, 3].reduce(0, :+)
# Using sum (available in Ruby 2.4+)
[1, 2, 3].sum
Return Value
reduce returns the final accumulated value. For empty collections:
- With initial value: returns that initial value
- Without initial value: returns
nil
Edge Cases
# Single element with initial value
[5].reduce(10, :+)
# => 15
# Single element without initial value
[5].reduce { |acc, x| acc + x }
# => 5
# With strings (using concatenation)
["a", "b", "c"].reduce(:+)
# => "abc"
See Also
Enumerable#inject— alias for reduceArray#sum— simpler for numeric sumsEnumerable#each_with_object— iterate while building an objectEnumerable#partition— split into two arrays by condition