Enumerable Patterns
Group By Intro
group_by builds a hash where each key points to matching values.
group by
`group_by` chooses a key for each item and collects items with the same key.
Group By Intro
group_by_intro.rb
Replay: real traced execution (multi-file project)
split_at = 5
numbers = [2, 4, 5, 8]
groups = numbers.group_by do |number|
number >= split_at ? "large" : "small"
end
small = groups.fetch("small", [])
large = groups.fetch("large", [])
puts "split_at=#{split_at}"
puts "small=#{small.join(",")}"
puts "large=#{large.join(",")}"
split_at = 4
numbers = [2, 4, 5, 8]
groups = numbers.group_by do |number|
number >= split_at ? "large" : "small"
end
small = groups.fetch("small", [])
large = groups.fetch("large", [])
puts "split_at=#{split_at}"
puts "small=#{small.join(",")}"
puts "large=#{large.join(",")}"
split_at = 7
numbers = [2, 4, 5, 8]
groups = numbers.group_by do |number|
number >= split_at ? "large" : "small"
end
small = groups.fetch("small", [])
large = groups.fetch("large", [])
puts "split_at=#{split_at}"
puts "small=#{small.join(",")}"
puts "large=#{large.join(",")}"
split_at ← 5, numbers ← [2, 4, 5, 8]
1split_at→ 5 = 5 #@split_at=4, 72numbers→ [2, 4, 5, 8] = [2, 4, 5, 8]34groups = numbers[2, 4, 5, 8].group_by do |number|5 number >= split_at ? "large" : "small"6enddo |number|
pass 1 of 44groups = numbers.group_by do |number2|5 number >= split_at ? "large" : "small"6endAll 4 passes — pass 1 is the card above pass numbernumbersgroups1 2 — — 2 4 — — 3 5 — — 4 8 [2, 4, 5, 8] {"small"=>[2, 4], "large"=>[5, 8]} small ← [2, 4], large ← [5, 8]
8small→ [2, 4] = groups.fetch("small", [])[2, 4]9large→ [5, 8] = groups.fetch("large", [])[5, 8]1011puts "split_at=#{split_at5}"12puts "small=#{small.join(",")2,4}"13puts "large=#{large.join(",")5,8}"outputsplit_at=5 small=2,4 large=5,8
split_at ← 4, numbers ← [2, 4, 5, 8]
1split_at→ 4 = 42numbers→ [2, 4, 5, 8] = [2, 4, 5, 8]34groups = numbers[2, 4, 5, 8].group_by do |number|5 number >= split_at ? "large" : "small"6enddo |number|
pass 1 of 44groups = numbers.group_by do |number2|5 number >= split_at ? "large" : "small"6endAll 4 passes — pass 1 is the card above pass numbernumbersgroups1 2 — — 2 4 — — 3 5 — — 4 8 [2, 4, 5, 8] {"small"=>[2], "large"=>[4, 5, 8]} small ← [2], large ← [4, 5, 8]
8small→ [2] = groups.fetch("small", [])[2]9large→ [4, 5, 8] = groups.fetch("large", [])[4, 5, 8]1011puts "split_at=#{split_at4}"12puts "small=#{small.join(",")2}"13puts "large=#{large.join(",")4,5,8}"outputsplit_at=4 small=2 large=4,5,8
split_at ← 7, numbers ← [2, 4, 5, 8]
1split_at→ 7 = 72numbers→ [2, 4, 5, 8] = [2, 4, 5, 8]34groups = numbers[2, 4, 5, 8].group_by do |number|5 number >= split_at ? "large" : "small"6enddo |number|
pass 1 of 44groups = numbers.group_by do |number2|5 number >= split_at ? "large" : "small"6endAll 4 passes — pass 1 is the card above pass numbernumbersgroups1 2 — — 2 4 — — 3 5 — — 4 8 [2, 4, 5, 8] {"small"=>[2, 4, 5], "large"=>[8]} small ← [2, 4, 5], large ← [8]
8small→ [2, 4, 5] = groups.fetch("small", [])[2, 4, 5]9large→ [8] = groups.fetch("large", [])[8]1011puts "split_at=#{split_at7}"12puts "small=#{small.join(",")2,4,5}"13puts "large=#{large.join(",")8}"outputsplit_at=7 small=2,4,5 large=8
Build the Buckets
- Start with
numbers:[2, 4, 5, 8]. - The block chooses
"small"or"large"for each number. group_byputs numbers with the same key together.fetchreads each bucket and uses an empty array if it is missing. | Number | Key whensplit_atis5| | --- | --- | |2|small| |4|small| |5|large| |8|large|
Exercise: group_by_intro.rb
Group numbers into small and large buckets, then print each bucket with an empty fallback