Functional Ruby Idioms
Map, Filter, Reduce
Functional Ruby often transforms a collection through small chained steps.
map filter reduce
`select`, `map`, and `reduce` can express filtering, transforming, and accumulating without manual index tracking.
Map, Filter, Reduce
map_filter_reduce.rb
Replay: real traced execution (multi-file project)
threshold = 3
numbers = [1, 2, 3, 4, 5]
filtered = numbers.select { |number| number > threshold }
doubled = filtered.map { |number| number * 2 }
total = doubled.reduce(0) { |sum, number| sum + number }
filtered_text = filtered.join("/")
doubled_text = doubled.join("/")
puts "threshold=#{threshold}"
puts "filtered=#{filtered_text}"
puts "doubled=#{doubled_text}"
puts "total=#{total}"
threshold = 2
numbers = [1, 2, 3, 4, 5]
filtered = numbers.select { |number| number > threshold }
doubled = filtered.map { |number| number * 2 }
total = doubled.reduce(0) { |sum, number| sum + number }
filtered_text = filtered.join("/")
doubled_text = doubled.join("/")
puts "threshold=#{threshold}"
puts "filtered=#{filtered_text}"
puts "doubled=#{doubled_text}"
puts "total=#{total}"
threshold = 4
numbers = [1, 2, 3, 4, 5]
filtered = numbers.select { |number| number > threshold }
doubled = filtered.map { |number| number * 2 }
total = doubled.reduce(0) { |sum, number| sum + number }
filtered_text = filtered.join("/")
doubled_text = doubled.join("/")
puts "threshold=#{threshold}"
puts "filtered=#{filtered_text}"
puts "doubled=#{doubled_text}"
puts "total=#{total}"
threshold ← 3, numbers ← [1, 2, 3, 4, 5], filtered ← [4, 5], doubled ← [8, 10]
1threshold→ 3 = 3 #@threshold=2, 42numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]34filtered→ [4, 5] = numbers[1, 2, 3, 4, 5].select { |number| number > threshold }5doubled→ [8, 10] = filtered[4, 5].map { |number| number * 2 }6total→ 18 = doubled[8, 10].reduce(0) { |sum, number| sum + number }78filtered_text→ 4/5 = filtered.join("/")4/59doubled_text→ 8/10 = doubled.join("/")8/101011puts "threshold=#{threshold3}"12puts "filtered=#{filtered_text4/5}"13puts "doubled=#{doubled_text8/10}"14puts "total=#{total18}"outputthreshold=3 filtered=4/5 doubled=8/10 total=18
threshold ← 2, numbers ← [1, 2, 3, 4, 5], filtered ← [3, 4, 5]
1threshold→ 2 = 22numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]34filtered→ [3, 4, 5] = numbers[1, 2, 3, 4, 5].select { |number| number > threshold }5doubled→ [6, 8, 10] = filtered[3, 4, 5].map { |number| number * 2 }6total→ 24 = doubled[6, 8, 10].reduce(0) { |sum, number| sum + number }78filtered_text→ 3/4/5 = filtered.join("/")3/4/59doubled_text→ 6/8/10 = doubled.join("/")6/8/101011puts "threshold=#{threshold2}"12puts "filtered=#{filtered_text3/4/5}"13puts "doubled=#{doubled_text6/8/10}"14puts "total=#{total24}"outputthreshold=2 filtered=3/4/5 doubled=6/8/10 total=24
threshold ← 4, numbers ← [1, 2, 3, 4, 5], filtered ← [5], doubled ← [10]
1threshold→ 4 = 42numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]34filtered→ [5] = numbers[1, 2, 3, 4, 5].select { |number| number > threshold }5doubled→ [10] = filtered[5].map { |number| number * 2 }6total→ 10 = doubled[10].reduce(0) { |sum, number| sum + number }78filtered_text→ 5 = filtered.join("/")59doubled_text→ 10 = doubled.join("/")101011puts "threshold=#{threshold4}"12puts "filtered=#{filtered_text5}"13puts "doubled=#{doubled_text10}"14puts "total=#{total10}"outputthreshold=4 filtered=5 doubled=10 total=10