reduce and inject accumulate collection values into one result.

reduce `reduce` passes the accumulated value and the next item to the block each step.

Reduce Inject

starting_total
reduce_inject.rb
Replay: real traced execution (multi-file project)
starting_total = 0
scores = [3, 4, 5]

total = scores.reduce(starting_total) do |sum, score|
  sum + score
end

puts "starting_total=#{starting_total}"
puts "scores=#{scores.join(",")}"
puts "total=#{total}"
starting_total = 5
scores = [3, 4, 5]

total = scores.reduce(starting_total) do |sum, score|
  sum + score
end

puts "starting_total=#{starting_total}"
puts "scores=#{scores.join(",")}"
puts "total=#{total}"
starting_total = 10
scores = [3, 4, 5]

total = scores.reduce(starting_total) do |sum, score|
  sum + score
end

puts "starting_total=#{starting_total}"
puts "scores=#{scores.join(",")}"
puts "total=#{total}"
  1. starting_total ← 0, scores ← [3, 4, 5]

    1starting_total→ 0 = 0  #@starting_total=5, 102scores→ [3, 4, 5] = [3, 4, 5]34total = scores[3, 4, 5].reduce(starting_total0) do |sum, score|5  sum + score6end
  2. do |sum, score|

    pass 1 of 3
    4total = scores.reduce(starting_total) do |sum0, score3|5  sum + score6end
    All 3 passes — pass 1 is the card above
    passsumscorescoresstarting_totaltotal
    103
    234
    375[3, 4, 5]012
  3. puts "starting_total=#{starting_total}"

    8puts "starting_total=#{starting_total0}"9puts "scores=#{scores.join(",")3,4,5}"10puts "total=#{total12}"
    outputstarting_total=0
    scores=3,4,5
    total=12
  1. starting_total ← 5, scores ← [3, 4, 5]

    1starting_total→ 5 = 52scores→ [3, 4, 5] = [3, 4, 5]34total = scores[3, 4, 5].reduce(starting_total5) do |sum, score|5  sum + score6end
  2. do |sum, score|

    pass 1 of 3
    4total = scores.reduce(starting_total) do |sum5, score3|5  sum + score6end
    All 3 passes — pass 1 is the card above
    passsumscorescoresstarting_totaltotal
    153
    284
    3125[3, 4, 5]517
  3. puts "starting_total=#{starting_total}"

    8puts "starting_total=#{starting_total5}"9puts "scores=#{scores.join(",")3,4,5}"10puts "total=#{total17}"
    outputstarting_total=5
    scores=3,4,5
    total=17
  1. starting_total ← 10, scores ← [3, 4, 5]

    1starting_total→ 10 = 102scores→ [3, 4, 5] = [3, 4, 5]34total = scores[3, 4, 5].reduce(starting_total10) do |sum, score|5  sum + score6end
  2. do |sum, score|

    pass 1 of 3
    4total = scores.reduce(starting_total) do |sum10, score3|5  sum + score6end
    All 3 passes — pass 1 is the card above
    passsumscorescoresstarting_totaltotal
    1103
    2134
    3175[3, 4, 5]1022
  3. puts "starting_total=#{starting_total}"

    8puts "starting_total=#{starting_total10}"9puts "scores=#{scores.join(",")3,4,5}"10puts "total=#{total22}"
    outputstarting_total=10
    scores=3,4,5
    total=22

Follow the Total

  1. Start the accumulator with starting_total.
  2. Add the first score to get a new total.
  3. Pass that total into the next step.
  4. After the last score, reduce returns the final total. | Step | Score | Accumulator after step | | --- | --- | --- | | start | none | 0 | | 1 | 3 | 3 | | 2 | 4 | 7 | | 3 | 5 | 12 |

Exercise: reduce_inject.rb

Use reduce to add scores starting from a chosen total and print the final total