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.
3a30e89c4d8db5738b5222c472e58255?d=identicon&s=25 Mark Watson (Guest)
on 2006-03-06 22: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.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-03-06 22:57
(Received via mailing list)
2006/3/6, Mark  Watson <mark.watson@gmail.com>:
> (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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-03-06 22:57
(Received via mailing list)
On Mar 6, 2006, at 3:48 PM, Mark Watson 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 Gray II
Da914f265213ce31c7d22195ef178d15?d=identicon&s=25 gordon (Guest)
on 2006-03-06 23:00
(Received via mailing list)
How about:


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

foo.zip(bar).each do |a,b|
  puts "#{a} #{b}"
end
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-03-06 23:03
(Received via mailing list)
On Mar 6, 2006, at 4:48 PM, Mark Watson 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
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2006-03-06 23:18
(Received via mailing list)
On 3/6/06, Mark  Watson <mark.watson@gmail.com> 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]
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2006-03-06 23: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
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-03-06 23:30
(Received via mailing list)
Hi --

On Tue, 7 Mar 2006, William James 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 (dblack@wobblini.net)
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
3a30e89c4d8db5738b5222c472e58255?d=identicon&s=25 Mark Watson (Guest)
on 2006-03-06 23: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.
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2006-03-06 23: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" }
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-03-07 00:28
(Received via mailing list)
On Mar 6, 2006, at 5:17 PM, Wilson Bilkovich 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__
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2006-03-07 00:40
(Received via mailing list)
dblack@wobblini.net 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.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-03-07 01:20
(Received via mailing list)
Hi --

On Tue, 7 Mar 2006, William James 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 (dblack@wobblini.net)
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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-03-07 02:32
(Received via mailing list)
On Mar 6, 2006, at 5:26 PM, Logan Capaldo 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 Gray II
This topic is locked and can not be replied to.