Enumerable Patterns
Reduce Inject
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
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}"
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 + score6enddo |sum, score|
pass 1 of 34total = scores.reduce(starting_total) do |sum0, score3|5 sum + score6endAll 3 passes — pass 1 is the card above pass sumscorescoresstarting_totaltotal1 0 3 — — — 2 3 4 — — — 3 7 5 [3, 4, 5] 0 12 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
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 + score6enddo |sum, score|
pass 1 of 34total = scores.reduce(starting_total) do |sum5, score3|5 sum + score6endAll 3 passes — pass 1 is the card above pass sumscorescoresstarting_totaltotal1 5 3 — — — 2 8 4 — — — 3 12 5 [3, 4, 5] 5 17 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
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 + score6enddo |sum, score|
pass 1 of 34total = scores.reduce(starting_total) do |sum10, score3|5 sum + score6endAll 3 passes — pass 1 is the card above pass sumscorescoresstarting_totaltotal1 10 3 — — — 2 13 4 — — — 3 17 5 [3, 4, 5] 10 22 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
- Start the accumulator with
starting_total. - Add the first score to get a new total.
- Pass that total into the next step.
- After the last score,
reducereturns 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