Iterating over an array n element at a time

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

On Sun, 6 Aug 2006, Kim P. wrote:

111
222
333

//kim

harp:~ > ruby -r enumerator -e’ %w( 1 2 3 4 5 ).each_slice(2){|slice| p
slice} ’
[“1”, “2”]
[“3”, “4”]
[“5”]

harp:~ > ruby -r enumerator -e’ %w( 1 2 3 4 5 ).each_cons(2){|slice| p
slice} ’
[“1”, “2”]
[“2”, “3”]
[“3”, “4”]
[“4”, “5”]

-a

require ‘enumerator’
[1,1,1,2,2,2,3,3,3].each_slice(3){|a,b,c|p [a,b,c]}

j`ey
http://www.eachmapinject.com

Kim P. wrote:

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.

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

end
require ‘facet/enumerable/each_by’
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}

Logan C. 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.

Trans wrote:

require ‘facet/enumerable/each_by’
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).

On 8/5/06, Martin DeMello [email protected] wrote:

a.each { |(x,y,z)| print x,y,z,"\n" }
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

Trans wrote:

prints…
a.each_by(3) { |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:

[email protected] ~
$ 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”
“-”

[email protected] ~
$

Kind regards

robert

On 8/6/06, Trans [email protected] wrote:

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

Robert K. wrote:

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

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.

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}

Hi,

Sorry about the real newbie interrupting the high level thread, but…

I liked very much the “eachn” method from Martin, and decided to test
it out. I got a “Undefined method ‘each_slice’” for the array. Went to
ruby-doc.org, and the core docs have each_slice defined in module
Enumerable. I have Ruby 1.8.4 installed. Does anyone know why is that
not working for me?

Thanks,
Marcelo A…

On 8/6/06, Marcelo A. [email protected] wrote:

Hi,

Sorry about the real newbie interrupting the high level thread, but…

I liked very much the “eachn” method from Martin, and decided to test
it out. I got a “Undefined method ‘each_slice’” for the array. Went to
ruby-doc.org, and the core docs have each_slice defined in module
Enumerable. I have Ruby 1.8.4 installed. Does anyone know why is that
not working for me?

Just a tiny little trap you fell into, look at this
[1,2,3].each_slice(2){|s| p s}
NoMethodError: undefined method `each_slice’ for [1, 2, 3]:Array
from (irb):1

but

irb(main):003:0> require ‘enumerator’
=> true
irb(main):004:0> [1,2,3].each_slice(2){|s| p s}
[1, 2]
[3]

I have fallen into that one more than once and I still will, it is a
little
bit unclear why Enumerable is not in the core while it is in the core
doc.
But well just a minor hickup.

Cheers
Robert
[SNIP]


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

On 8/7/06, Marcelo A. [email protected] wrote:

Hi,

Sorry about the real newbie interrupting the high level thread, but…

I liked very much the “eachn” method from Martin, and decided to test
it out. I got a “Undefined method ‘each_slice’” for the array. Went to
ruby-doc.org, and the core docs have each_slice defined in module
Enumerable. I have Ruby 1.8.4 installed. Does anyone know why is that
not working for me?

You need to require ‘enumerator’, which adds additional methods like
each_slice to Enumerable.

martin

On 8/6/06, Trans [email protected] wrote:

print x,y,z,"\n"

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

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

T.

I might be wrong, but I can’t see how these parameter markers can be
implemented without a lot of changes.

The syntax of block literals needs to be changed to allow the markers,
then the Proc class needs to be changes so that the methods like
select can see the markers, then all the methods in Enumerable (and
anywhere else they are reimplemented e.g. Hash), need to be changed to
be sensitive to them, and make them “slurpable.”

It seems like these “slurp indicators” are trying to move the loop
control out of the internal iterators, and to make the block look a
teeny bit like a java style iterator in some strange sense, which
makes the idea seem a little less ruby-like.

Martin DeMello’s eachn method is a neat trick which makes use of
existing mechanisms. but I suspect that making such stuff general
isn’t such a good idea for Ruby, maybe for a forked language (sluby?)
for those who like such stuff.

For Ruby, I think that Nakada-san’s suggestion is a better way to
compose such functionality.

Rick DeNatale

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/

[1, 2]
[3]

I have fallen into that one more than once and I still will, it is a little
bit unclear why Enumerable is not in the core while it is in the core doc.
But well just a minor hickup.

Oh, I see! Thanks for the pointer.

I thought Array mixed that in, so it should be defined for it. But
then again, I’m still getting used to modules, mixins and such. Been
too long in a Java-only world…

Thanks again,
Marcelo A…

On 8/7/06, Marcelo A. [email protected] wrote:

[1, 2]
too long in a Java-only world…
Array does mix Enumerable in. However, the core Enumerable module
doesn’t include each_slice; that is provided by the ‘enumerator’
library, which reopens Enumerable and adds some methods to it. Note
that enumerator is in the standard lib rather than in the core.

http://www.ruby-doc.org/stdlib/libdoc/enumerator/rdoc/index.html

martin

On 8/6/06, Rick DeNatale [email protected] wrote:

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.

Huh - you’re right, block.call(i) works nicely without the splat. I
guess it’s because the argument list ‘picks apart’ the array. Good
catch.

martin

Rick DeNatale wrote:

For Ruby, I think that Nakada-san’s suggestion is a better way to
compose such functionality.

Yes, I agree. I had forgotten about that.

T.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs