Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > What is the best way to iterate through two containers of the same length?

Reply
Thread Tools

What is the best way to iterate through two containers of the same length?

 
 
Mark Watson
Guest
Posts: n/a
 
      03-06-2006
If I have two containers c1 and c2 of the same length, what is the
proper "Ruby way" to do this:

c1.length.times {|i|
# access c1[i], c2[i]
}

I like that Ruby container classes provide their own iterators, but
what I would like to have is something like:

(c1,c2).each {|x1,x2| .... }

I thought of writing my own iterator class so that I could do something
like:

Iterator.new(c1,c2).each {|x1,x2| .... }

but that looks clumsy and inefficient.

I am transitioning to using mostly Ruby (moving away from Java, Lisp,
and Smalltalk) and I would like to use the proper Ruby idioms.

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      03-06-2006
2006/3/6, Mark Watson <>:
> If I have two containers c1 and c2 of the same length, what is the
> proper "Ruby way" to do this:
>
> c1.length.times {|i|
> # access c1[i], c2[i]
> }
>
> I like that Ruby container classes provide their own iterators, but
> what I would like to have is something like:
>
> (c1,c2).each {|x1,x2| .... }
>
> I thought of writing my own iterator class so that I could do something
> like:
>
> Iterator.new(c1,c2).each {|x1,x2| .... }
>
> but that looks clumsy and inefficient.
>
> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
> and Smalltalk) and I would like to use the proper Ruby idioms.


If the two are arrays you can use Array#zip:

>> %w{foo bar baz}.zip([1,2,3]) {|a,b| print a, "-", b,"\n"}

foo-1
bar-2
baz-3

For the more general case you can look at Generator
http://ruby-doc.org/stdlib/libdoc/generator/rdoc/

Kind regards

robert

--
Have a look: http://www.flickr.com/photos/fussel-foto/


 
Reply With Quote
 
 
 
 
James Edward Gray II
Guest
Posts: n/a
 
      03-06-2006
On Mar 6, 2006, at 3:48 PM, Mark Watson wrote:

> If I have two containers c1 and c2 of the same length, what is the
> proper "Ruby way" to do this:
>
> c1.length.times {|i|
> # access c1[i], c2[i]
> }
>
> I like that Ruby container classes provide their own iterators, but
> what I would like to have is something like:
>
> (c1,c2).each {|x1,x2| .... }


You are looking for Enumerable#zip:

>> letters = %w{A B C}

=> ["A", "B", "C"]
>> numbers = [1, 2, 3]

=> [1, 2, 3]
>> letters.zip(numbers) do |letter, number|

?> puts "#{letter}#{number}"
>> end

A1
B2
C3
=> nil

You can also use the standard generator library to turn Ruby's
internal iterators into external iterators (like Java's iterators) if
needed.

Hope that helps.

James Edward Gray II



 
Reply With Quote
 
gordon
Guest
Posts: n/a
 
      03-06-2006
How about:


foo = ["foo","foo"]
bar = ["bar","bar"]

foo.zip(bar).each do |a,b|
puts "#{a} #{b}"
end

 
Reply With Quote
 
Logan Capaldo
Guest
Posts: n/a
 
      03-06-2006

On Mar 6, 2006, at 4:48 PM, Mark Watson wrote:

> If I have two containers c1 and c2 of the same length, what is the
> proper "Ruby way" to do this:
>
> c1.length.times {|i|
> # access c1[i], c2[i]
> }
>
> I like that Ruby container classes provide their own iterators, but
> what I would like to have is something like:
>
> (c1,c2).each {|x1,x2| .... }
>
> I thought of writing my own iterator class so that I could do
> something
> like:
>
> Iterator.new(c1,c2).each {|x1,x2| .... }
>
> but that looks clumsy and inefficient.
>
> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
> and Smalltalk) and I would like to use the proper Ruby idioms.
>
>


Well there is zip:
irb(main):001:0> [1,2,3].zip([4,5,6]) do |a, b|
irb(main):002:1* puts "#{a} #{b}"
irb(main):003:1> end
1 4
2 5
3 6
=> nil



 
Reply With Quote
 
Wilson Bilkovich
Guest
Posts: n/a
 
      03-06-2006
On 3/6/06, Mark Watson <> wrote:
> If I have two containers c1 and c2 of the same length, what is the
> proper "Ruby way" to do this:
>
> c1.length.times {|i|
> # access c1[i], c2[i]
> }
>
> I like that Ruby container classes provide their own iterators, but
> what I would like to have is something like:
>
> (c1,c2).each {|x1,x2| .... }
>
> I thought of writing my own iterator class so that I could do something
> like:
>
> Iterator.new(c1,c2).each {|x1,x2| .... }
>
> but that looks clumsy and inefficient.
>
> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
> and Smalltalk) and I would like to use the proper Ruby idioms.
>


One way I'm fond of is:
require 'generator'
enum =3D SyncEnumerator.new([1,2,3], [7,8,9])
enum.each do |pair|
puts pair.inspect
end
# Results in:
[1, 7]
[2, 8]
[3, 9]


 
Reply With Quote
 
William James
Guest
Posts: n/a
 
      03-06-2006
Mark Watson wrote:
> If I have two containers c1 and c2 of the same length, what is the
> proper "Ruby way" to do this:
>
> c1.length.times {|i|
> # access c1[i], c2[i]
> }
>
> I like that Ruby container classes provide their own iterators, but
> what I would like to have is something like:
>
> (c1,c2).each {|x1,x2| .... }
>
> I thought of writing my own iterator class so that I could do something
> like:
>
> Iterator.new(c1,c2).each {|x1,x2| .... }
>
> but that looks clumsy and inefficient.
>
> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
> and Smalltalk) and I would like to use the proper Ruby idioms.


foo = %w(x y z) ; bar = [2,4,6]
[foo, bar].transpose.each{|a,b| print a, b, $/ }
--->
x2
y4
z6

 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      03-06-2006
Hi --

On Tue, 7 Mar 2006, William James wrote:

> Mark Watson wrote:
>> If I have two containers c1 and c2 of the same length, what is the
>> proper "Ruby way" to do this:
>>
>> c1.length.times {|i|
>> # access c1[i], c2[i]
>> }
>>
>> I like that Ruby container classes provide their own iterators, but
>> what I would like to have is something like:
>>
>> (c1,c2).each {|x1,x2| .... }
>>
>> I thought of writing my own iterator class so that I could do something
>> like:
>>
>> Iterator.new(c1,c2).each {|x1,x2| .... }
>>
>> but that looks clumsy and inefficient.
>>
>> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
>> and Smalltalk) and I would like to use the proper Ruby idioms.

>
> foo = %w(x y z) ; bar = [2,4,6]
> [foo, bar].transpose.each{|a,b| print a, b, $/ }
> --->
> x2
> y4
> z6


I don't think $/ is very idiomatic. See the ToDo file in the source;
it includes:

* discourage use of symbol variables (e.g. $/, etc.) in manual




David

--
David A. Black ()
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


 
Reply With Quote
 
Mark Watson
Guest
Posts: n/a
 
      03-06-2006
Thanks everyone - just wht I was looking for. The SyncEnumerator class
is fine in general, and using zip is what I wanted for arrays.

 
Reply With Quote
 
William James
Guest
Posts: n/a
 
      03-06-2006
Mark Watson wrote:
> If I have two containers c1 and c2 of the same length, what is the
> proper "Ruby way" to do this:
>
> c1.length.times {|i|
> # access c1[i], c2[i]
> }
>
> I like that Ruby container classes provide their own iterators, but
> what I would like to have is something like:
>
> (c1,c2).each {|x1,x2| .... }
>
> I thought of writing my own iterator class so that I could do something
> like:
>
> Iterator.new(c1,c2).each {|x1,x2| .... }
>
> but that looks clumsy and inefficient.
>
> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
> and Smalltalk) and I would like to use the proper Ruby idioms.


class Array
def pairs
first.each_with_index{|a,i|
yield a, last[i]
}
end
end

[%w(x y z), [2,4,6]].pairs{|a,b| print a,b,"\n" }

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to iterate 2 nested collections w <logic:iterate> without a"getter" John Java 4 04-01-2008 09:46 AM
Containers of iterators vs. containers of references clark.coleman@att.net C++ 7 01-25-2008 01:37 PM
nested:iterate or logic: iterate with multibox?? runescience Java 0 02-09-2006 12:57 AM
Best way of comparing two containers? Dylan C++ 13 07-09-2004 05:14 PM
<logic:iterate /> iterate beyond items in the collection Gogo Java 1 09-04-2003 08:40 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57