Is iterating in lock-step possible?

I have been wondering is there is a way to do this. Can I have two
itertors working in lock-step - ie, can I have both of them return a
value each into the same loop body ?

a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a.each {|a1|
    b.each {|b1|
        # this nests the call to b inside a
    }
}

Is there someway I can do something like -
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
(a.each, b.each) {|a1, b1|
  #so that I get one value from a and one from b
}

I hope I have made the idea clear, the above syntax is only illustrative
of what I mean.

This is possible in python because the iterators are fundamentally
objects that require an explicit next() call and are not bound to the
the loop body/block by syntax as in ruby.

Thanks in advance,
Roshan

Hello Roshan,

you can use the Generator class, to wrap any iterator into a generator
(i.e. get a .next function)

Or in simple cases where the additional memory overhead is not
important, you can also use the zip funtion. I.e.

%w(eins zwei drei).zip([1,2,3]).each do | name, value |
  puts "The value of #{name} is #{value}"
end

regards,

Brian

···

On Thu, 10 Mar 2005 21:52:43 +0900, Roshan James <roshanj@microsoft.com> wrote:

I have been wondering is there is a way to do this. Can I have two
itertors working in lock-step - ie, can I have both of them return a
value each into the same loop body ?

a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a.each {|a1|
    b.each {|b1|
        # this nests the call to b inside a
    }
}

Is there someway I can do something like -
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
(a.each, b.each) {|a1, b1|
        #so that I get one value from a and one from b
}

I hope I have made the idea clear, the above syntax is only illustrative
of what I mean.

This is possible in python because the iterators are fundamentally
objects that require an explicit next() call and are not bound to the
the loop body/block by syntax as in ruby.

Thanks in advance,
Roshan

--
Brian Schröder
http://ruby.brian-schroeder.de/

Is there someway I can do something like -
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
(a.each, b.each) {|a1, b1|
        #so that I get one value from a and one from b
}

Warning: total Ruby newby naive approach:

a = (1..4).to_a

=> [1, 2, 3, 4]

b = (5..8).to_a

=> [5, 6, 7, 8]

a.each_with_index {|av, ai| p [av, b[ai]]}

[1, 5]
[2, 6]
[3, 7]
[4, 8]

···

On Thu, 10 Mar 2005 21:52:43 +0900, Roshan James <roshanj@microsoft.com> wrote:

--
Regards,
Jason
http://blog.casey-sweat.us/

Or in simple cases where the additional memory overhead is not
important, you can also use the zip funtion. I.e.

%w(eins zwei drei).zip([1,2,3]).each do | name, value |
  puts "The value of #{name} is #{value}"
end

Why do you use #each ?

svg% ruby -e '%w(eins zwei drei).zip([1,2,3]) {|a, b| puts "#{a} #{b}" }'
eins 1
zwei 2
drei 3
svg%

no memory overhead

Guy Decoux

Thank you, I thought that was something not yet in the standard lib.
Wasn't there a discussion about this on this list not so long ago?
Anyway, learned something more.

regards,

Brian

···

On Thu, 10 Mar 2005 22:06:10 +0900, ts <decoux@moulon.inra.fr> wrote:

> Or in simple cases where the additional memory overhead is not
> important, you can also use the zip funtion. I.e.

> %w(eins zwei drei).zip([1,2,3]).each do | name, value |
> puts "The value of #{name} is #{value}"
> end

Why do you use #each ?

svg% ruby -e '%w(eins zwei drei).zip([1,2,3]) {|a, b| puts "#{a} #{b}" }'
eins 1
zwei 2
drei 3
svg%

no memory overhead

Guy Decoux

--
Brian Schröder
http://ruby.brian-schroeder.de/

I needed to do this the other day, but I was too embarassed to ask. :frowning:

···

On Thu, 10 Mar 2005 23:28:24 +0900, Brian Schröder <ruby.brian@gmail.com> wrote:

On Thu, 10 Mar 2005 22:06:10 +0900, ts <decoux@moulon.inra.fr> wrote:

>
> > Or in simple cases where the additional memory overhead is not
> > important, you can also use the zip funtion. I.e.
>
> > %w(eins zwei drei).zip([1,2,3]).each do | name, value |
> > puts "The value of #{name} is #{value}"
> > end
>
> Why do you use #each ?
>
> svg% ruby -e '%w(eins zwei drei).zip([1,2,3]) {|a, b| puts "#{a} #{b}" }'
> eins 1
> zwei 2
> drei 3
> svg%
>
> no memory overhead
>
> Guy Decoux
>
>

Thank you, I thought that was something not yet in the standard lib.
Wasn't there a discussion about this on this list not so long ago?
Anyway, learned something more.

regards,

Brian

--
Brian Schröder
http://ruby.brian-schroeder.de/

--
Thomas G. Willis
http://paperbackmusic.net

Hi --

···

On Thu, 10 Mar 2005, [ISO-8859-1] Brian Schröder wrote:

On Thu, 10 Mar 2005 22:06:10 +0900, ts <decoux@moulon.inra.fr> wrote:

> Or in simple cases where the additional memory overhead is not
> important, you can also use the zip funtion. I.e.

> %w(eins zwei drei).zip([1,2,3]).each do | name, value |
> puts "The value of #{name} is #{value}"
> end

Why do you use #each ?

svg% ruby -e '%w(eins zwei drei).zip([1,2,3]) {|a, b| puts "#{a} #{b}" }'
eins 1
zwei 2
drei 3
svg%

no memory overhead

Guy Decoux

Thank you, I thought that was something not yet in the standard lib.
Wasn't there a discussion about this on this list not so long ago?

I think you might be thinking of discussion of the return value for
#zip when a block is used -- that is, whether it should return the
zipped array (as it does when there's no block) instead of nil.

David

--
David A. Black
dblack@wobblini.net