What is the best way to iterate through two containers of th

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.

2006/3/6, Mark Watson [email protected]:

(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

On Mar 6, 2006, at 3:48 PM, Mark W. wrote:

(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 G. II

How about:

foo = [“foo”,“foo”]
bar = [“bar”,“bar”]

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

On 3/6/06, Mark Watson [email protected] wrote:

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

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

Results in:

[1, 7]
[2, 8]
[3, 9]

Mark Watson wrote:

(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

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

(c1,c2).each {|x1,x2| … }
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

Hi –

On Tue, 7 Mar 2006, William J. wrote:

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

:slight_smile:

David


David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails

Thanks everyone - just wht I was looking for. The SyncEnumerator class
is fine in general, and using zip is what I wanted for arrays.

Mark Watson wrote:

(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" }

[email protected] wrote:

}

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

:slight_smile:

David

idiomatic, adj. Peculiar to a particular group or individual.

“\n” is found in C and in awk, but $/ isn’t; so it is more
nearly peculiar to Ruby. Some may lack the capacity to remember
what it represents.

However, I have no doubt that this is an unfashionable opinion
and that your view is the dominant one.


idiot, n. A member of a large and powerful tribe whose influence in
human affairs has always been dominant and controlling. … He sets
the fashions of opinion and taste, dictates the limitations of speech,
and circumscribes conduct with a dead-line.

On Mar 6, 2006, at 5:17 PM, Wilson B. wrote:

[3, 9]
Warning, SyncEnumerator is slow, and you probably don’t need it
since #zip is in enumerable.
Run the below for a demonstration. Original I had it run each
benchmark 10 times by the way, but I never had the patience to let
the syncenum versions finish:

% cat zip_vs_syncenum.rb
require ‘benchmark’
require ‘generator’
a = (1…100)
b = a.to_a.reverse

puts “Using zip:”
Benchmark.bm { |x|
x.report {
3.times { a.zip(b) { |x, y| z = x * y } }
}
}
puts “Using SyncEnumerator(new every time):”
Benchmark.bm { |x|
x.report {
3.times {
a_b_enum = SyncEnumerator.new(a, b)
a_b_enum.each { |x, y| z = x * y }
}
}
}

puts “Using SyncEnumerator(only one created):”
Benchmark.bm { |x|
x.report {
a_b_enum = SyncEnumerator.new(a, b)
3.times { a_b_enum.each { |x, y| z = x * y } }
}
}

END

On Mar 6, 2006, at 5:26 PM, Logan C. wrote:

Warning, SyncEnumerator is slow…

It was recently reworked to use threads instead of continuations,
this resulted in a pretty significant speed boost. I doubt it beats
Enumerable#zip yet, but the speed will be nice.

James Edward G. II

Hi –

On Tue, 7 Mar 2006, William J. wrote:

access c1[i], c2[i]

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

idiomatic, adj. Peculiar to a particular group or individual.

“\n” is found in C and in awk, but $/ isn’t; so it is more
nearly peculiar to Ruby. Some may lack the capacity to remember
what it represents.

However, I have no doubt that this is an unfashionable opinion
and that your view is the dominant one.

I share your opinion that $/ is not in C or awk, but is in Ruby :slight_smile:
I’m thinking more about its position within Ruby, which isn’t
directly connected to its presence or absence anywhere else. It’s
there, but it seems to be in a bit of a shaky position.

David


David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails