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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mark W. (Guest)
on 2006-03-06 23:50
(Received via mailing list)
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.
Robert K. (Guest)
on 2006-03-06 23:57
(Received via mailing list)
2006/3/6, Mark  Watson <removed_email_address@domain.invalid>:
> (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
James G. (Guest)
on 2006-03-06 23:57
(Received via mailing list)
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
gordon (Guest)
on 2006-03-07 00:00
(Received via mailing list)
How about:


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

foo.zip(bar).each do |a,b|
  puts "#{a} #{b}"
end
Logan C. (Guest)
on 2006-03-07 00:03
(Received via mailing list)
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
Wilson B. (Guest)
on 2006-03-07 00:18
(Received via mailing list)
On 3/6/06, Mark  Watson <removed_email_address@domain.invalid> 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]
William J. (Guest)
on 2006-03-07 00:21
(Received via mailing list)
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
unknown (Guest)
on 2006-03-07 00:30
(Received via mailing list)
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

:-)


David

--
David A. Black (removed_email_address@domain.invalid)
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
Mark W. (Guest)
on 2006-03-07 00:33
(Received via mailing list)
Thanks everyone - just wht I was looking for. The SyncEnumerator class
is fine in general, and using zip is what I wanted for arrays.
William J. (Guest)
on 2006-03-07 00:40
(Received via mailing list)
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" }
Logan C. (Guest)
on 2006-03-07 01:28
(Received via mailing list)
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__
William J. (Guest)
on 2006-03-07 01:40
(Received via mailing list)
removed_email_address@domain.invalid 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
>
> :-)
>
>
> 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.
unknown (Guest)
on 2006-03-07 02:20
(Received via mailing list)
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 :-)
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 (removed_email_address@domain.invalid)
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
James G. (Guest)
on 2006-03-07 03:32
(Received via mailing list)
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
This topic is locked and can not be replied to.