In message "[ruby-talk:5239] Running two iterators in parallel"
on 00/10/03, Dan Schmidt <dfan / harmonixmusic.com> writes:
|I have two iterators. I would like to run them in parallel, creating
|an iterator that generates arrays containing one element from each.
|
|That is, I'd like to write 'combine' so that I can say:
|
| def it1 ()
| yield 1; yield 2; yield 3
| end
|
| def it2 ()
| yield 4; yield 5; yield 6
| end
|
| combine('it1','it2') { |x|
| # x is (1, 4), then (2, 5), then (3, 6)
| }
|
|Some more things:
|
| - I don't want to have to modify it1 and it2 in order to write combine.
| - Ideally, combine could take an arbitrary number of iterators as
| arguments.
| - Assume that the iterators cannot just be rewritten to provide a big
| array all at once instead of iterating.
|
|I imagine this could be done with threads (ew). I bet it could be
|done with continuations, but I spent a few hours last night and didn't
|get anywhere (I still have trouble understanding continuations). Or
|maybe there's some built-in language support that I haven't found yet.
|
|Can anyone solve this puzzle?
Use threads.
require 'thread'
def combine(*args)
queues = []
for it in args
queue = Queue.new
Thread.start(it, queue) do |i,q|
self.send(it) do |x|
q.push x
end
end
queues.push queue
end
begin
loop do
ary = []
for q,th in queues
ary.push q.pop
end
yield ary
end
rescue ThreadError
# no more items, exit
end
end
--
matz.