Ruby Tuesday – Enumerable#reduce aka inject

Today’s Ruby Tuesday is Enumerable#reduce, also known as Enumerable#inject.

Enumerable#reduce works against an enum and takes a initial value for the accumulator and two parameter block. The first parameter to the block is the current accumulated value, and second parameter is the current element in the iteration. If no accumulator value is specified, the first item in the enum is taken to be used as the accumulator value.

["baz","Supercalifragilisticexpialidocious", "qwerty"].reduce("") do |shortest, item|
  item.length < shortest.length ? item : shortest
end
# => ""
["baz","Supercalifragilisticexpialidocious", "qwerty"].reduce do |longest, item|
  item.length > longest.length ? item : longest
end
# => "Supercalifragilisticexpialidocious"
["baz", "Supercalifragilisticexpialidocious", "qwerty"].reduce do |shortest, item|
  item.length < shortest.length ? item : shortest
end
# => "baz"

Calling reduce on an empty enum just returns the accumulator, or if no initial value for the accumulator given returns the result of calling first on the enum, which in the case of Array is nil.

[].reduce(:accum){|accum, item| accum * item}
# => :accum
[].reduce{|accum, item| accum * item}
# => nil

Enumerable#reduce can also take a symbol instead of a block, which is the name of the method to invoke on the accumulator value. This form of reduce also takes an initial accumulator value, or uses the first item as the accumulator.

[1, 2, 3, 4, 5].reduce(:+)
# => 15
[1, 2, 3, 4, 5].reduce(:*)
# => 120
[1, 2, 3, 4, 5].reduce(10, :*)
# => 1200
[100, 10, 2].reduce(:/)
# => 5
[100, 10, 2].reduce(1_000_000, :/)
# => 500

–Proctor