reduce and inject
reduce (an exact alias of inject) is Enumerable's method for folding a collection down into a single accumulated value — a sum, a maximum, a hash, or any other combined result built up element by element. Where map produces a collection of the same size and select produces a subset, reduce can produce literally anything: a number, a string, a hash, even another array, by repeatedly combining an accumulator with each element via a block or a symbol representing an operator.
Cricket analogy: reduce is like a scorer tallying every ball bowled in an innings into one final total, unlike map which would just relabel each ball, or select which would only keep the boundaries — reduce folds everything into a single combined number.
Basic usage: block form
In block form, reduce takes an optional initial value and yields |accumulator, element| to the block on each iteration; the block's return value becomes the accumulator for the next iteration. If no initial value is given, the first element of the collection is used as the starting accumulator, and iteration begins from the second element.
Cricket analogy: reduce yielding |accumulator, element| is like a scorer carrying the running total forward ball by ball; if no starting score is given, the first ball's runs become the initial total and tallying begins from the second delivery.
numbers = [1, 2, 3, 4, 5]
sum = numbers.reduce(0) { |acc, n| acc + n }
#=> 15
product = numbers.reduce(1) { |acc, n| acc * n }
#=> 120
max_value = numbers.reduce { |acc, n| n > acc ? n : acc }
#=> 5 (no initial value; starts with first element)Symbol shorthand and building complex structures
When the operation is a simple binary operator, reduce accepts a symbol instead of a block: reduce(:+) or reduce(0, :+). This shorthand reads cleanly for arithmetic but doesn't help for anything more complex, like building a Hash from an array — a very common real-world use of reduce.
Cricket analogy: reduce(:+) is like a scorer simply summing runs with a shorthand tally sheet, quick for totals, but building a detailed wagon-wheel breakdown by shot type needs the full block form, not just the symbol shorthand.
total = [10, 20, 30].reduce(:+) #=> 60
words = ['apple', 'banana', 'kiwi']
word_lengths = words.reduce({}) do |acc, word|
acc[word] = word.length
acc
end
#=> {'apple' => 5, 'banana' => 6, 'kiwi' => 4}'Reduce' (or 'fold') is a functional programming staple found across languages: JavaScript's Array.prototype.reduce, Python's functools.reduce, and Haskell's foldl/foldr all express the same idea — collapsing a sequence into one value via a repeatedly applied combining function. Ruby's naming it both reduce and inject (Smalltalk's original term, inject:into:) is a nod to its Smalltalk heritage.
Forgetting to return the accumulator from the block is a classic bug when building complex structures. In the Hash-building example above, forgetting the trailing acc line would make the block's return value be word.length (the last expression), silently corrupting the accumulator on the next iteration.
reduceandinjectare exact aliases; both fold a collection into a single accumulated value.- Block form yields
|accumulator, element|; the block's return value becomes the next accumulator. - Without an initial value, the first element seeds the accumulator and iteration starts from the second.
- Symbol shorthand like
reduce(:+)works for simple binary operators. reducecan build any result type — numbers, hashes, arrays, custom objects — not just sums.- Always return the accumulator explicitly from the block, especially when building complex structures.
Practice what you learned
1. What is the relationship between `reduce` and `inject` in Ruby?
2. In `numbers.reduce { |acc, n| acc + n }` with no initial value, what seeds the accumulator?
3. What does `[1, 2, 3].reduce(:+)` return?
4. What must a reduce block do at its end when building a complex accumulator like a Hash?
5. Besides Ruby, which language term originally inspired the name 'inject'?
Was this page helpful?
You May Also Like
each, map, and select
Master the three most commonly used Enumerable methods — each for side effects, map for transformation, and select for filtering — and when to reach for which.
Comparable and Enumerable Modules
See how Ruby's Comparable and Enumerable modules let a class gain dozens of methods for free by implementing just one core method each: `<=>` or `each`.
Enumerable Deep Dive
Go beyond map and select to explore Enumerable's full toolkit — sort_by, group_by, partition, each_with_object, lazy enumerators, and more — for expressive collection processing.
Hashes in Ruby
How Ruby's Hash class stores key-value pairs, including modern literal syntax, symbol keys, default values, and the Enumerable methods it inherits.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics