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
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
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
On Sun, 6 Aug 2006, 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"
endprints...
111
222
333//kim
--
happiness is not something ready-made. it comes from your own actions.
- h.h. the 14th dali lama
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
On 8/5/06, Kim Pedersen <kimersen@online.no> 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"
endprints...
111
222
333//kim
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"
endprints...
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.
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"
endprints...
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
333But 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}
On Aug 5, 2006, at 3:20 PM, Trans wrote:
T.
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"
endprints...
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
333But 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).
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
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.
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"
endprints...
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
333But 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
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.
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
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
enda = (1..10).to_a
a.eachn {|x,y,z| p [x,y,z]}
--
Rick DeNatale
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.
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
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]
On 8/6/06, Marcelo Alvim <malvim@gmail.com> 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?
--
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
You need to require 'enumerator', which adds additional methods like
each_slice to Enumerable.
martin
On 8/7/06, Marcelo Alvim <malvim@gmail.com> 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?
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
On 8/6/06, Rick DeNatale <rick.denatale@gmail.com> wrote:
On 8/5/06, Martin DeMello <martindemello@gmail.com> wrote:
> 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.
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.
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):1but
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.
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 Alvim.
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/7/06, Marcelo Alvim <malvim@gmail.com> wrote:
> 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.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...
Actually it is in both
http://www.ruby-doc.org/core/classes/Enumerable.html
James, might it not be a good idea to get it out of the Core Doc?
Robert
On 8/6/06, Martin DeMello <martindemello@gmail.com> wrote:
On 8/7/06, Marcelo Alvim <malvim@gmail.com> wrote:
[SNIP]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
--
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