[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Iterating over an array n element at a time

Kim Pedersen

8/5/2006 6:12:00 PM

Is there an elegant way to iterate over an array n elements at a time?
e.g. something like...

a = [1,1,1,2,2,2,3,3,3]

a.each(3) do |x,y,z|
print x,y,z,"\n"
end

prints...
111
222
333

//kim

17 Answers

Ara.T.Howard

8/5/2006 6:16:00 PM

0

Trans

8/5/2006 7:21:00 PM

0


Kim Pedersen wrote:
> Is there an elegant way to iterate over an array n elements at a time?
> e.g. something like...
>
> a = [1,1,1,2,2,2,3,3,3]
>
> a.each(3) do |x,y,z|
> print x,y,z,"\n"
> end
>
> prints...
> 111
> 222
> 333
>
> //kim

enumerator is probably better since it is built-in, but...

require 'facet/enumerable/each_by'
a = [1,1,1,2,2,2,3,3,3]
a.each_by(3) { |x,y,z| print x,y,z,"\n" }
111
222
333

But why not have Ruby fill those arguments out automatically? This
already does:

a = [[1,1,1],[2,2,2],[3,3,3]]
a.each { |x,y,z| print x,y,z,"\n" }

So couldn't some "slurping" indicator be used?

a = [1,1,1,2,2,2,3,3,3]
a.each { |(x,y,z)| print x,y,z,"\n" }

Or something.

T.


Logan Capaldo

8/5/2006 7:28:00 PM

0


On Aug 5, 2006, at 3:20 PM, Trans wrote:

>
> Kim Pedersen wrote:
>> Is there an elegant way to iterate over an array n elements at a
>> time?
>> e.g. something like...
>>
>> a = [1,1,1,2,2,2,3,3,3]
>>
>> a.each(3) do |x,y,z|
>> print x,y,z,"\n"
>> end
>>
>> prints...
>> 111
>> 222
>> 333
>>
>> //kim
>
> enumerator is probably better since it is built-in, but...
>
> require 'facet/enumerable/each_by'
> a = [1,1,1,2,2,2,3,3,3]
> a.each_by(3) { |x,y,z| print x,y,z,"\n" }
> 111
> 222
> 333
>
> But why not have Ruby fill those arguments out automatically? This
> already does:
>
> a = [[1,1,1],[2,2,2],[3,3,3]]
> a.each { |x,y,z| print x,y,z,"\n" }
>
> So couldn't some "slurping" indicator be used?
>
> a = [1,1,1,2,2,2,3,3,3]
> a.each { |(x,y,z)| print x,y,z,"\n" }
>
> Or something.
>
( ) already have meaning in block arguments though
e.g.:

{ :a => 1, :b => 2 }.inject({}) { |h, (k, v)| h[k] = v + 1; h }
#=> {:b=>3, :a=>2}

> T.
>
>


M. Edward (Ed) Borasky

8/5/2006 7:31:00 PM

0

Trans wrote:
> Kim Pedersen wrote:
>
>> Is there an elegant way to iterate over an array n elements at a time?
>> e.g. something like...
>>
>> a = [1,1,1,2,2,2,3,3,3]
>>
>> a.each(3) do |x,y,z|
>> print x,y,z,"\n"
>> end
>>
>> prints...
>> 111
>> 222
>> 333
>>
>> //kim
>>
>
> enumerator is probably better since it is built-in, but...
>
> require 'facet/enumerable/each_by'
> a = [1,1,1,2,2,2,3,3,3]
> a.each_by(3) { |x,y,z| print x,y,z,"\n" }
> 111
> 222
> 333
>
> But why not have Ruby fill those arguments out automatically? This
> already does:
>
> a = [[1,1,1],[2,2,2],[3,3,3]]
> a.each { |x,y,z| print x,y,z,"\n" }
>
> So couldn't some "slurping" indicator be used?
>
> a = [1,1,1,2,2,2,3,3,3]
> a.each { |(x,y,z)| print x,y,z,"\n" }
>
> Or something.
>
> T.
>
I think I'd recast the array as a matrix and then iterate over rows (or
columns, depending on which way you did the recast).

Trans

8/5/2006 9:07:00 PM

0


Logan Capaldo wrote:

> ( ) already have meaning in block arguments though
> e.g.:
>
> { :a => 1, :b => 2 }.inject({}) { |h, (k, v)| h[k] = v + 1; h }
> #=> {:b=>3, :a=>2}

Right, but it seems to be similar in nature. Could it not be used for
both?

Otherwise another notation

{ |[x,y,z]| ... }

perhaps.

T.

Martin DeMello

8/5/2006 9:13:00 PM

0

On 8/6/06, Trans <transfire@gmail.com> wrote:
> But why not have Ruby fill those arguments out automatically? This
> already does:
>
> a = [[1,1,1],[2,2,2],[3,3,3]]
> a.each { |x,y,z| print x,y,z,"\n" }
>
> So couldn't some "slurping" indicator be used?
>
> a = [1,1,1,2,2,2,3,3,3]
> a.each { |(x,y,z)| print x,y,z,"\n" }
>
> Or something.

require 'enumerator'

module Enumerable
def eachn(&block)
n = block.arity
each_slice(n) {|i| block.call(*i)}
end
end

a = (1..10).to_a
a.eachn {|x,y,z| p [x,y,z]}

martin

Rick DeNatale

8/6/2006 4:12:00 AM

0

On 8/5/06, Martin DeMello <martindemello@gmail.com> wrote:
> On 8/6/06, Trans <transfire@gmail.com> wrote:
> > But why not have Ruby fill those arguments out automatically? This
> > already does:
> >
> > a = [[1,1,1],[2,2,2],[3,3,3]]
> > a.each { |x,y,z| print x,y,z,"\n" }
> >
> > So couldn't some "slurping" indicator be used?
> >
> > a = [1,1,1,2,2,2,3,3,3]
> > a.each { |(x,y,z)| print x,y,z,"\n" }
> >
> > Or something.
>
> require 'enumerator'
>
> module Enumerable
> def eachn(&block)
> n = block.arity
> each_slice(n) {|i| block.call(*i)}
> end
> end
>
> a = (1..10).to_a
> a.eachn {|x,y,z| p [x,y,z]}

Nice! As it turns out that *i in the block.call invocation isn't
needed. The proc call method does the right thing in this case.

Also there's no need to turn the range into an array, it'll work
directly since ranges mixin Enumerable

--
Rick DeNatale

Robert Klemme

8/6/2006 8:31:00 AM

0

Trans wrote:
> Kim Pedersen wrote:
>> Is there an elegant way to iterate over an array n elements at a time?
>> e.g. something like...
>>
>> a = [1,1,1,2,2,2,3,3,3]
>>
>> a.each(3) do |x,y,z|
>> print x,y,z,"\n"
>> end
>>
>> prints...
>> 111
>> 222
>> 333
>>
>> //kim
>
> enumerator is probably better since it is built-in, but...
>
> require 'facet/enumerable/each_by'
> a = [1,1,1,2,2,2,3,3,3]
> a.each_by(3) { |x,y,z| print x,y,z,"\n" }
> 111
> 222
> 333
>
> But why not have Ruby fill those arguments out automatically? This
> already does:
>
> a = [[1,1,1],[2,2,2],[3,3,3]]
> a.each { |x,y,z| print x,y,z,"\n" }
>
> So couldn't some "slurping" indicator be used?
>
> a = [1,1,1,2,2,2,3,3,3]
> a.each { |(x,y,z)| print x,y,z,"\n" }
>
> Or something.
>
> T.
>
>
Note though that your code does something different than each_cons which
moves a sliding window while your code iterates in chunks! See:

robert@fussel ~
$ ruby -r enumerator -e' %w( 1 2 3 4 5 ).each_cons(2){|a, b| p a, b,
"-"} '
"1"
"2"
"-"
"2"
"3"
"-"
"3"
"4"
"-"
"4"
"5"
"-"

robert@fussel ~
$

Kind regards

robert

Trans

8/6/2006 10:56:00 AM

0


Robert Klemme wrote:
> Trans wrote:
> > Kim Pedersen wrote:
> >> Is there an elegant way to iterate over an array n elements at a time?
> >> e.g. something like...
> >>
> >> a = [1,1,1,2,2,2,3,3,3]
> >>
> >> a.each(3) do |x,y,z|
> >> print x,y,z,"\n"
> >> end
> >>
> >> prints...
> >> 111
> >> 222
> >> 333
> >>
> >> //kim
> >
> > enumerator is probably better since it is built-in, but...
> >
> > require 'facet/enumerable/each_by'
> > a = [1,1,1,2,2,2,3,3,3]
> > a.each_by(3) { |x,y,z| print x,y,z,"\n" }
> > 111
> > 222
> > 333
> >
> > But why not have Ruby fill those arguments out automatically? This
> > already does:
> >
> > a = [[1,1,1],[2,2,2],[3,3,3]]
> > a.each { |x,y,z| print x,y,z,"\n" }
> >
> > So couldn't some "slurping" indicator be used?
> >
> > a = [1,1,1,2,2,2,3,3,3]
> > a.each { |(x,y,z)| print x,y,z,"\n" }
> >
> > Or something.
> >
> > T.
> >
> >
> Note though that your code does something different than each_cons which
> moves a sliding window while your code iterates in chunks! See:

Right. But wasn't that what was originally asked for? In any case, I
am only meaning the "chunk" case with my example, but certainly one
could conceive of a notion to "slide" too. The advantage of notation
over more methods is that it works with derivatives. Eg. pseudo code:

[1,1,2,2,3,4].select { |slide(a,b)| a == b }

Otherwise you need a select_slice, select_cons, collect_slice,
collect_cons, and so on.

T.


Nobuyoshi Nakada

8/6/2006 11:41:00 AM

0

Hi,

At Sun, 6 Aug 2006 19:55:37 +0900,
Trans wrote in [ruby-talk:206591]:
> [1,1,2,2,3,4].select { |slide(a,b)| a == b }
>
> Otherwise you need a select_slice, select_cons, collect_slice,
> collect_cons, and so on.

Longer a little, but it's possible with enumerator.

[1,1,2,2,3,4].enum_cons(2).select {|a, b| a == b}

--
Nobu Nakada