Cyclic array

I would like to print n elements from an Array in a cyclic way.

I mean :

using anArray = [ "a", "b", "c", "d", "e", "f", "g"], I should do :

anArray.print_cyclic(4, 0) => "a", "b", "c", "d" (first print 4 elements starting with the first one)

anArray.print_cyclic_next => "b", "c", "d", "e"
anArray.print_cyclic_next => "c", "d", "e", "f"
anArray.print_cyclic_next => "d", "e", "f", "g"
anArray.print_cyclic_next => "e", "f", "g", "a"
anArray.print_cyclic_next => "f", "g", "a", "b"
anArray.print_cyclic_next => "g", "a", "b", "c"
.....
also in reverse cycle
anArray.print_cyclic(4, 0) => "a", "b", "c", "d"
anArray.print_cyclic_previous => "g", "a", "b", "c"
anArray.print_cyclic_previous => "f", "g", "a", "b",

what could be the simplest way to do it ? no simple way using Array class methods only ,
should I define a class and methods to loop into the array ? any existing lib ? if it has been already done why should I rewrite it ....

tfyh

joss

sounds like classic (?) Ruby. you just need a block. in the block, get the array size, move element 0 to end. do block until satisfied.

···

On Apr 28, 2007, at 10:10 PM, Josselin wrote:

I would like to print n elements from an Array in a cyclic way.

I mean :

using anArray = [ "a", "b", "c", "d", "e", "f", "g"], I should do :

anArray.print_cyclic(4, 0) => "a", "b", "c", "d" (first print 4 elements starting with the first one)

anArray.print_cyclic_next => "b", "c", "d", "e"
anArray.print_cyclic_next => "c", "d", "e", "f"
anArray.print_cyclic_next => "d", "e", "f", "g"
anArray.print_cyclic_next => "e", "f", "g", "a"
anArray.print_cyclic_next => "f", "g", "a", "b"
anArray.print_cyclic_next => "g", "a", "b", "c"
.....
also in reverse cycle
anArray.print_cyclic(4, 0) => "a", "b", "c", "d"
anArray.print_cyclic_previous => "g", "a", "b", "c"
anArray.print_cyclic_previous => "f", "g", "a", "b",

what could be the simplest way to do it ? no simple way using Array class methods only ,
should I define a class and methods to loop into the array ? any existing lib ? if it has been already done why should I rewrite it ....

tfyh

joss

This will do the shifting but I'm not sure about wrapping around.

require 'enumerator'
(1..25).each_cons(5) do |x|
p x
end

Harry

···

On 4/28/07, Josselin <josselin@wanadoo.fr> wrote:

I would like to print n elements from an Array in a cyclic way.

I mean :

using anArray = [ "a", "b", "c", "d", "e", "f", "g"], I should do :

anArray.print_cyclic(4, 0) => "a", "b", "c", "d" (first print 4
elements starting with the first one)

anArray.print_cyclic_next => "b", "c", "d", "e"
anArray.print_cyclic_next => "c", "d", "e", "f"
anArray.print_cyclic_next => "d", "e", "f", "g"
anArray.print_cyclic_next => "e", "f", "g", "a"
anArray.print_cyclic_next => "f", "g", "a", "b"
anArray.print_cyclic_next => "g", "a", "b", "c"
.....
also in reverse cycle
anArray.print_cyclic(4, 0) => "a", "b", "c", "d"
anArray.print_cyclic_previous => "g", "a", "b", "c"
anArray.print_cyclic_previous => "f", "g", "a", "b",

what could be the simplest way to do it ? no simple way using Array
class methods only ,
should I define a class and methods to loop into the array ? any
existing lib ? if it has been already done why should I rewrite it ....

tfyh

joss

--

A Look into Japanese Ruby List in English

This is a possible approach:

   module Enumerable
     def each_cycle(window, start=0)
       (start...length+start).each do |i|
         yield((i..i+window).map {|n| self[n % length]})
       end
     end
   end

Usage is:

   a = [ "a", "b", "c", "d", "e", "f", "g"]
   a.each_cycle(4) do |cycle|
     puts "#{cycle}"
   end

You can delegate reverse cycle to each_cycle on the reverse (and perhaps taking the opposite of start mod length, depending on the meaning of start).

-- fxn

···

On Apr 28, 2007, at 3:10 PM, Josselin wrote:

I would like to print n elements from an Array in a cyclic way.

I mean :

using anArray = [ "a", "b", "c", "d", "e", "f", "g"], I should do :

anArray.print_cyclic(4, 0) => "a", "b", "c", "d" (first print 4 elements starting with the first one)

anArray.print_cyclic_next => "b", "c", "d", "e"
anArray.print_cyclic_next => "c", "d", "e", "f"
anArray.print_cyclic_next => "d", "e", "f", "g"
anArray.print_cyclic_next => "e", "f", "g", "a"
anArray.print_cyclic_next => "f", "g", "a", "b"
anArray.print_cyclic_next => "g", "a", "b", "c"
.....
also in reverse cycle
anArray.print_cyclic(4, 0) => "a", "b", "c", "d"
anArray.print_cyclic_previous => "g", "a", "b", "c"
anArray.print_cyclic_previous => "f", "g", "a", "b",

what could be the simplest way to do it ? no simple way using Array class methods only ,
should I define a class and methods to loop into the array ? any existing lib ? if it has been already done why should I rewrite it ....

Not a direct answer to your question, but regarding circular lists
(which can be created from an array):
http://phrogz.net/RubyLibs/rdoc/files/Ouroboros_rb.html

···

On Apr 28, 7:05 am, Josselin <josse...@wanadoo.fr> wrote:

I would like to print n elements from an Array in a cyclic way.

Thanks to all of u . As always different ways .. the most difficult step for a newbie is : where should I start ?

joss

···

On 2007-04-28 15:05:48 +0200, Josselin <josselin@wanadoo.fr> said:

I would like to print n elements from an Array in a cyclic way.

I mean :

using anArray = [ "a", "b", "c", "d", "e", "f", "g"], I should do :

anArray.print_cyclic(4, 0) => "a", "b", "c", "d" (first print 4 elements starting with the first one)

anArray.print_cyclic_next => "b", "c", "d", "e"
anArray.print_cyclic_next => "c", "d", "e", "f"
anArray.print_cyclic_next => "d", "e", "f", "g"
anArray.print_cyclic_next => "e", "f", "g", "a"
anArray.print_cyclic_next => "f", "g", "a", "b"
anArray.print_cyclic_next => "g", "a", "b", "c"
.....
also in reverse cycle
anArray.print_cyclic(4, 0) => "a", "b", "c", "d"
anArray.print_cyclic_previous => "g", "a", "b", "c"
anArray.print_cyclic_previous => "f", "g", "a", "b",

what could be the simplest way to do it ? no simple way using Array class methods only ,
should I define a class and methods to loop into the array ? any existing lib ? if it has been already done why should I rewrite it ....

tfyh

joss

Try something like this.

arr = ("a".."g").to_a
(1..25).each do |d|
arr.push << arr.shift
p arr.slice(0..5)
end

Harry

···

On 4/28/07, Josselin <josselin@wanadoo.fr> wrote:

what could be the simplest way to do it ? no simple way using Array
class methods only ,

--

A Look into Japanese Ruby List in English

what could be the simplest way to do it ? no simple way using Array
class methods only ,

Sorry for the double post.
In my mail the code got chopped off at the bottom.

Try this.

arr = ("a".."g").to_a
(1..25).each do |d|
arr.push << arr.shift
p arr.slice(0..5)
end

Harry

···

--

A Look into Japanese Ruby List in English

what could be the simplest way to do it ? no simple way using Array
class methods only ,

I did a poor job of cleaning that code.
It had unnecessary stuff in it.
Sorry, my brain is not working today.

arr = ("a".."g").to_a
(1..25).each do
arr << arr.shift
p arr.slice(0..5)
end

Harry

···

--

A Look into Japanese Ruby List in English

Indeed, as a newbie myself, (forever I think) it is often a bit overwhelming where to start.
A common method is to sit down with pen and paper and write out the ideas, brainstorming. Figure out what you want to do. then break each part down into it's components. it doesn't have to be in code yet. That's almost the easy fun part, translating your ideas into code.
It really is a design process. Some snippets that you create or do often enough will stick in your mind and you'll be able to apply them quicker with practice. But pseudo code is always a good thing, if you comment it out, it is instant documentation! (if necessary.

···

On Apr 29, 2007, at 12:10 AM, Josselin wrote:

On 2007-04-28 15:05:48 +0200, Josselin <josselin@wanadoo.fr> said:

I would like to print n elements from an Array in a cyclic way.
I mean :
using anArray = [ "a", "b", "c", "d", "e", "f", "g"], I should do :
anArray.print_cyclic(4, 0) => "a", "b", "c", "d" (first print 4 elements starting with the first one)
anArray.print_cyclic_next => "b", "c", "d", "e"
anArray.print_cyclic_next => "c", "d", "e", "f"
anArray.print_cyclic_next => "d", "e", "f", "g"
anArray.print_cyclic_next => "e", "f", "g", "a"
anArray.print_cyclic_next => "f", "g", "a", "b"
anArray.print_cyclic_next => "g", "a", "b", "c"
.....
also in reverse cycle
anArray.print_cyclic(4, 0) => "a", "b", "c", "d"
anArray.print_cyclic_previous => "g", "a", "b", "c"
anArray.print_cyclic_previous => "f", "g", "a", "b",
what could be the simplest way to do it ? no simple way using Array class methods only ,
should I define a class and methods to loop into the array ? any existing lib ? if it has been already done why should I rewrite it ....
tfyh
joss

Thanks to all of u . As always different ways .. the most difficult step for a newbie is : where should I start ?

joss

Xavier Noria wrote:
...

  module Enumerable
    def each_cycle(window, start=0)
      (start...length+start).each do |i|
        yield((i..i+window).map {|n| self[n % length]})
      end
    end
  end

Here is a slight variation, for amusement, but it doesn't work for window > length:

   module Enumerable
     def each_cycle(window, start = 0)
       (-length+start...start).each do |i|
         yield values_at(*(i..i+window))
       end
     end
   end

   a = [ "a", "b", "c", "d", "e", "f", "g"]
   a.each_cycle(4) do |cycle|
     puts "#{cycle}"
   end

   a.each_cycle(14) do |cycle|
     puts "#{cycle}"
   end

__END__

abcde
bcdef
cdefg
defga
efgab
fgabc
gabcd

abcdefgabcdefg
bcdefgabcdefg
cdefgabcdefg
defgabcdefg
efgabcdefg
fgabcdefg
gabcdefg

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Expanding on its usage for the stated problem:

irb(main):001:0> require 'Ouroboros.rb'
=> true
irb(main):002:0> anArray = [ "a", "b", "c", "d", "e", "f", "g"]
=> ["a", "b", "c", "d", "e", "f", "g"]
irb(main):003:0> aSnake = Ouroboros.from_a anArray
=> #<Ouroboros:0x367810 @current_index=0, @current="a", @all=["a",
"b", "c", "d", "e", "f", "g"], @size=7>
irb(main):004:0> aSnake.to_a[ 0...4 ]
=> ["a", "b", "c", "d"]
irb(main):005:0> aSnake.increment
=> ["b"]
irb(main):006:0> aSnake.to_a[ 0...4 ]
=> ["b", "c", "d", "e"]
irb(main):008:0> aSnake.increment
=> "c"
irb(main):009:0> aSnake.to_a[ 0...4 ]
=> ["c", "d", "e", "f"]

...and so on.

···

On Apr 28, 7:58 am, Phrogz <g...@refinery.com> wrote:

On Apr 28, 7:05 am, Josselin <josse...@wanadoo.fr> wrote:

> I would like to print n elements from an Array in a cyclic way.

Not a direct answer to your question, but regarding circular lists
(which can be created from an array):
File: Ouroboros.rb

This method won't work for Enumerables in general, although I guess it
does work for Arrays.

Not all enumerables have one or both length or methods.

···

On 4/28/07, Xavier Noria <fxn@hashref.com> wrote:

This is a possible approach:

   module Enumerable
     def each_cycle(window, start=0)
       (start...length+start).each do |i|
         yield((i..i+window).map {|n| self[n % length]})
       end
     end
   end

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Oh right, thank you. I don't know why ri Enumerable lists length here, looks like it is getting non-core methods from somewhere else. I overlooked though. The OP wanted this for an Array, it would certainly work there.

-- fxn

···

On Apr 30, 2007, at 3:43 AM, Rick DeNatale wrote:

On 4/28/07, Xavier Noria <fxn@hashref.com> wrote:

This is a possible approach:

   module Enumerable
     def each_cycle(window, start=0)
       (start...length+start).each do |i|
         yield((i..i+window).map {|n| self[n % length]})
       end
     end
   end

This method won't work for Enumerables in general, although I guess it
does work for Arrays.

Not all enumerables have one or both length or methods.

By "there" I mean defining that method in Array, leaving the definition in Enumerable is broken.

-- fxn

···

On Apr 30, 2007, at 11:13 AM, Xavier Noria wrote:

This method won't work for Enumerables in general, although I guess it
does work for Arrays.

Not all enumerables have one or both length or methods.

Oh right, thank you. I don't know why ri Enumerable lists length here, looks like it is getting non-core methods from somewhere else. I overlooked though. The OP wanted this for an Array, it would certainly work there.

By the way I think that there's a typo that should be an open range in
the yield expression, otherwise you get

     yield((i...i+window).map {|n| self[n % length]})

Thinking about the Enumerable vs. Array aspect of this got me thinking
abou the subtleties of duck typing leading to another blog entry:

http://talklikeaduck.denhaven2.com/articles/2007/04/30/our-kind-of-ducks-odd-ducks-and-trained-ducks

···

On 4/30/07, Xavier Noria <fxn@hashref.com> wrote:

On Apr 30, 2007, at 3:43 AM, Rick DeNatale wrote:

> On 4/28/07, Xavier Noria <fxn@hashref.com> wrote:
>
>>
>> This is a possible approach:
>>
>> module Enumerable
>> def each_cycle(window, start=0)
>> (start...length+start).each do |i|
>> yield((i..i+window).map {|n| self[n % length]})
>> end
>> end
>> end
>
> This method won't work for Enumerables in general, although I guess it
> does work for Arrays.
>
> Not all enumerables have one or both length or methods.

Oh right, thank you. I don't know why ri Enumerable lists length
here, looks like it is getting non-core methods from somewhere else.
I overlooked though. The OP wanted this for an Array, it would
certainly work there.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

It took me a while to discover where that non-core Enumerable#length reported by ri/fri comes from, it is defined by RGL in the file

   rgl-0.2.3/lib/rgl/base.rb

I've learned that ri offers --system the hard way :-).

-- fxn

···

On Apr 30, 2007, at 11:13 AM, Xavier Noria wrote:

On Apr 30, 2007, at 3:43 AM, Rick DeNatale wrote:

On 4/28/07, Xavier Noria <fxn@hashref.com> wrote:

This is a possible approach:

   module Enumerable
     def each_cycle(window, start=0)
       (start...length+start).each do |i|
         yield((i..i+window).map {|n| self[n % length]})
       end
     end
   end

This method won't work for Enumerables in general, although I guess it
does work for Arrays.

Not all enumerables have one or both length or methods.

Oh right, thank you. I don't know why ri Enumerable lists length here

This is a possible approach:

   module Enumerable
     def each_cycle(window, start=0)
       (start...length+start).each do |i|
         yield((i..i+window).map {|n| self[n % length]})
       end
     end
   end

This method won't work for Enumerables in general, although I guess it
does work for Arrays.

Not all enumerables have one or both length or methods.

Oh right, thank you. I don't know why ri Enumerable lists length here

It took me a while to discover where that non-core Enumerable#length reported by ri/fri comes from, it is defined by RGL in the file

  rgl-0.2.3/lib/rgl/base.rb

I've learned that ri offers --system the hard way :-).

-- fxn

For those who aren't reading Rick's blog (where this is now in a comment):

module Enumerable
   def each_cycle(window, start=0)
     wrap_start =
     cache =
     each_with_index do |e,i|
       cache << e
       if i >= start + (window - 1)
         yield cache[start, window]
         cache.shift
       else
         wrap_start << e
       end
     end
     wrap_start.each do |e|
       cache << e
       yield cache[start, window]
       cache.shift
     end
     self
   end
end

Then you can each_cycle anything that is Enumerable, like a Range:
>> (1..5).each_cycle(3) {|x| p x}
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 1]
[5, 1, 2]
=> 1..5
>> { 'dog' => 'Rover', 'cat' => 'Mittens', 'fish' => 'Goldie' }.each_cycle(2) {|x| p x}
[["cat", "Mittens"], ["fish", "Goldie"]]
[["fish", "Goldie"], ["dog", "Rover"]]
[["dog", "Rover"], ["cat", "Mittens"]]
=> {"cat"=>"Mittens", "fish"=>"Goldie", "dog"=>"Rover"}

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On May 1, 2007, at 9:05 AM, Xavier Noria wrote:

On Apr 30, 2007, at 11:13 AM, Xavier Noria wrote:

On Apr 30, 2007, at 3:43 AM, Rick DeNatale wrote:

On 4/28/07, Xavier Noria <fxn@hashref.com> wrote: