I'm writing a method to merge two streams of numbers, and I've two alternative implementations:
def merge1(l1, l2)
Enumerator.new do |yielder|
h = case l1.peek <=> l2.peek
when -1 then l1.next
when +1 then l2.next
else l1.next; l2.next
end
yielder << h
yielder << merge1(l1, l2).next
end.lazy
end
def merge2(l1, l2)
Enumerator.new do |yielder|
loop do
h = case l1.peek <=> l2.peek
when -1 then l1.next
when +1 then l2.next
else l1.next; l2.next
end
yielder << h
end
end.lazy
end
puts merge2((1..Float::INFINITY).lazy.map {|x| x * 2}, (1..Float::INFINITY).lazy.map {|x| x * 3}).first(10)
But merge1 only prints "2 3" while merge2 produces the correct result.
You need to yield each item that sub-enumerator generate:
def merge1(l1, l2)
Enumerator.new do |yielder|
h = case l1.peek <=> l2.peek
when -1 then l1.next
when +1 then l2.next
else l1.next; l2.next
end
yielder << h
merge1(l1, l2).each do |h| # <----
yielder << h # <----
end # <----
end.lazy
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With