[RCR] Array.step

harp:~ > cat a.rb
class Array
   def self.step i, *a, &b
     j, s, ignored = *a
     i, j = 0, i if j.nil?
     s ||= (j < i ? -1 : 1)
     list = new
     i.step(j,s){|k| list << k}
     list.map! &b if b
     list
   end
end

require 'irb/xmp'

xmp 'Array.step(0,4)'
xmp 'Array.step(0,-4)'

xmp 'Array.step(1,5,2)'
xmp 'Array.step(-1,-5,-2)'

xmp 'Array.step 2'
xmp 'Array.step -2'

xmp 'Array.step(0,7){|i| 2 ** i}'
xmp 'even = Array.step(9){|i| i.modulo(2).zero?}'

harp:~ > ruby a.rb
Array.step(0,4)
     ==>[0, 1, 2, 3, 4]
Array.step(0,-4)
     ==>[0, -1, -2, -3, -4]
Array.step(1,5,2)
     ==>[1, 3, 5]
Array.step(-1,-5,-2)
     ==>[-1, -3, -5]
Array.step 2
     ==>[0, 1, 2]
Array.step -2
     ==>[0, -1, -2]
Array.step(0,7){|i| 2 ** i}
     ==>[1, 2, 4, 8, 16, 32, 64, 128]
even = Array.step(9){|i| i.modulo(2).zero?}
     ==>[true, false, true, false, true, false, true, false, true, false]

-a

···

--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

require 'enumerator'
class Array
   def self.step(i, *a, &block)
     b = block || lambda { |x| x }
     i.to_enum(:step, *a).map(&b)
   end
end

···

On Aug 30, 2006, at 1:12 PM, ara.t.howard@noaa.gov wrote:

harp:~ > cat a.rb
class Array
  def self.step i, *a, &b
    j, s, ignored = *a
    i, j = 0, i if j.nil?
    s ||= (j < i ? -1 : 1)
    list = new
    i.step(j,s){|k| list << k}
    list.map! &b if b
    list
  end
end

What's wrong with the block form of Array.new?

Array.new(5) { |i| i }
Array.new(5) { |i| -i }
Array.new(3) { |i| 1+2*i }
Array.new(3) { |i| -(1+2*i) }
Array.new(3) { |i| i }
Array.new(3) { |i| -i }
Array.new(8){ |i| 2 ** i }
Array.new(10){ |i| i.modulo(2).zero? }

···

On 8/30/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

harp:~ > cat a.rb
class Array
   def self.step i, *a, &b
     j, s, ignored = *a
     i, j = 0, i if j.nil?
     s ||= (j < i ? -1 : 1)
     list = new
     i.step(j,s){|k| list << k}
     list.map! &b if b
     list
   end
end

require 'irb/xmp'

xmp 'Array.step(0,4)'
xmp 'Array.step(0,-4)'

xmp 'Array.step(1,5,2)'
xmp 'Array.step(-1,-5,-2)'

xmp 'Array.step 2'
xmp 'Array.step -2'

xmp 'Array.step(0,7){|i| 2 ** i}'
xmp 'even = Array.step(9){|i| i.modulo(2).zero?}'

harp:~ > ruby a.rb
Array.step(0,4)
     ==>[0, 1, 2, 3, 4]
Array.step(0,-4)
     ==>[0, -1, -2, -3, -4]
Array.step(1,5,2)
     ==>[1, 3, 5]
Array.step(-1,-5,-2)
     ==>[-1, -3, -5]
Array.step 2
     ==>[0, 1, 2]
Array.step -2
     ==>[0, -1, -2]
Array.step(0,7){|i| 2 ** i}
     ==>[1, 2, 4, 8, 16, 32, 64, 128]
even = Array.step(9){|i| i.modulo(2).zero?}
     ==>[true, false, true, false, true, false, true, false, true, false]

I like it. Although also:

  require 'facet/interval'

  Interval.new(0,4).to_a => [ 0, 1, 2, 3, 4]
  Interval.new(0,4).to_a(2) => [ 0, 2, 4 ]

etc. And it has many other applications.

T.

···

ara.t.howard@noaa.gov wrote:

harp:~ > cat a.rb
class Array
   def self.step i, *a, &b
     j, s, ignored = *a
     i, j = 0, i if j.nil?
     s ||= (j < i ? -1 : 1)
     list = new
     i.step(j,s){|k| list << k}
     list.map! &b if b
     list
   end
end

require 'irb/xmp'

xmp 'Array.step(0,4)'
xmp 'Array.step(0,-4)'

xmp 'Array.step(1,5,2)'
xmp 'Array.step(-1,-5,-2)'

xmp 'Array.step 2'
xmp 'Array.step -2'

xmp 'Array.step(0,7){|i| 2 ** i}'
xmp 'even = Array.step(9){|i| i.modulo(2).zero?}'

harp:~ > ruby a.rb
Array.step(0,4)
     ==>[0, 1, 2, 3, 4]
Array.step(0,-4)
     ==>[0, -1, -2, -3, -4]
Array.step(1,5,2)
     ==>[1, 3, 5]
Array.step(-1,-5,-2)
     ==>[-1, -3, -5]
Array.step 2
     ==>[0, 1, 2]
Array.step -2
     ==>[0, -1, -2]
Array.step(0,7){|i| 2 ** i}
     ==>[1, 2, 4, 8, 16, 32, 64, 128]
even = Array.step(9){|i| i.modulo(2).zero?}
     ==>[true, false, true, false, true, false, true, false, true, false]

I think this would be a perfect use for the new automatic enumerators,
to avoid passing two opaque parameters to a method:

# to generate an array
5.upto(10).step(2).to_a

# or the other way around
5.step(2).upto(10).to_a

# or if you'd rather use a range
(5..10).step(2).to_a

# to step over an existing array
ary.step(3)
ary[0..5].step(2)

etc.

martin

···

On 8/30/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

xmp 'Array.step(0,4)'
xmp 'Array.step(0,-4)'

xmp 'Array.step(1,5,2)'
xmp 'Array.step(-1,-5,-2)'

xmp 'Array.step 2'
xmp 'Array.step -2'

xmp 'Array.step(0,7){|i| 2 ** i}'
xmp 'even = Array.step(9){|i| i.modulo(2).zero?}'

harp:~ > cat a.rb
class Array
  def self.step i, *a, &b
    j, s, ignored = *a
    i, j = 0, i if j.nil?
    s ||= (j < i ? -1 : 1)
    list = new
    i.step(j,s){|k| list << k}
    list.map! &b if b
    list
  end
end

Oops, minor addition follows:

require 'enumerator'
class Array
  def self.step(i, *a, &block)
    b = block || lambda { |x| x }

+ i, a[0] = 0, i if a.empty?

···

On Aug 30, 2006, at 1:43 PM, Logan Capaldo wrote:

On Aug 30, 2006, at 1:12 PM, ara.t.howard@noaa.gov wrote:
    i.to_enum(:step, *a).map(&b)
  end
end

you'll have to write almost as many lines as i did to make all of it work
though, still - i had forgotten about that:

harp:~ > cat a.rb
require 'enumerator'
class Array
  def self.step(i, *a, &block)
    b = block || lambda { |x| x }
    i.to_enum(:step, *a).map(&b)
  end
end

require 'irb/xmp'

xmp 'Array.step(0,4)'
xmp 'Array.step(0,-4)'

xmp 'Array.step(1,5,2)'
xmp 'Array.step(-1,-5,-2)'

xmp 'Array.step 2'
xmp 'Array.step -2'

xmp 'Array.step(0,7){|i| 2 ** i}'
xmp 'even = Array.step(9){|i| i.modulo(2).zero?}'

harp:~ > ruby a.rb
Array.step(0,4)
     ==>[0, 1, 2, 3, 4]
Array.step(0,-4)
     ==> # <- this one's wrong
Array.step(1,5,2)
     ==>[1, 3, 5]
Array.step(-1,-5,-2)
     ==>[-1, -3, -5]
Array.step 2
ArgumentError: wrong number of arguments
         from a.rb:17:in `step'
         from (irb):1
Array.step -2
ArgumentError: wrong number of arguments
         from a.rb:17:in `step'
         from (irb):1
Array.step(0,7){|i| 2 ** i}
     ==>[1, 2, 4, 8, 16, 32, 64, 128]
even = Array.step(9){|i| i.modulo(2).zero?}
ArgumentError: wrong number of arguments
         from a.rb:17:in `step'
         from (irb):1

regards.

-a

···

On Thu, 31 Aug 2006, Logan Capaldo wrote:

require 'enumerator'
class Array
def self.step(i, *a, &block)
   b = block || lambda { |x| x }
   i.to_enum(:step, *a).map(&b)
end
end

--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

nothing. just verbosity and brain power requirements :wink:

-a

···

On Thu, 31 Aug 2006, Eric Mahurin wrote:

What's wrong with the block form of Array.new?

Array.new(5) { |i| i }
Array.new(5) { |i| -i }
Array.new(3) { |i| 1+2*i }
Array.new(3) { |i| -(1+2*i) }
Array.new(3) { |i| i }
Array.new(3) { |i| -i }
Array.new(8){ |i| 2 ** i }
Array.new(10){ |i| i.modulo(2).zero? }

--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

I'd almost rather make the RCR for changing step rather than adding Array.step. It's more general, and with 1.9 magic iterators I think it would obviate the need to even have Array.step, e.g.: 1.step(3).to_a. Make n.step { ... } work as well and make it walk backwards if its from high to low.

···

On Aug 30, 2006, at 1:52 PM, ara.t.howard@noaa.gov wrote:

Array.step(0,-4)
    ==> # <- this one's wrong

indeed. just to be clear, however, the RCR is for Array.step not the exact
impl. the reason i wrote the one i did is because it can be translated to C
easily.

regards.

-a

···

On Thu, 31 Aug 2006, Logan Capaldo wrote:

On Aug 30, 2006, at 1:52 PM, ara.t.howard@noaa.gov wrote:

Array.step(0,-4)
    ==> # <- this one's wrong

I'd almost rather make the RCR for changing step rather than adding Array.step. It's more general, and with 1.9 magic iterators I think it would obviate the need to even have Array.step, e.g.: 1.step(3).to_a. Make n.step { ... } work as well and make it walk backwards if its from high to low.

--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

Hi,

At Thu, 31 Aug 2006 03:02:14 +0900,
Logan Capaldo wrote in [ruby-talk:211561]:

I'd almost rather make the RCR for changing step rather than adding
Array.step. It's more general, and with 1.9 magic iterators I think
it would obviate the need to even have Array.step, e.g.: 1.step
(3).to_a. Make n.step { ... } work as well and make it walk backwards
if its from high to low.

Do you mean this?

  $ ruby -v -e 'p 1.step(5,2).to_a'
  ruby 1.9.0 (2006-08-29) [i686-linux]
  [1, 3, 5]

···

--
Nobu Nakada

Array.step(0,-4)
    ==> # <- this one's wrong

I'd almost rather make the RCR for changing step rather than adding Array.step. It's more general, and with 1.9 magic iterators I think it would obviate the need to even have Array.step, e.g.: 1.step(3).to_a. Make n.step { ... } work as well and make it walk backwards if its from high to low.

indeed. just to be clear, however, the RCR is for Array.step not the exact
impl. the reason i wrote the one i did is because it can be translated to C
easily.

Well I don't really care persay about the implementation (I was just having fun with the golf), just the semantics. I still think this RCR would be better served as an addition of these capabilities to Numeric#step, and then if desired also an Array.step. That's just my opinion though.

···

On Aug 30, 2006, at 5:45 PM, ara.t.howard@noaa.gov wrote:

On Thu, 31 Aug 2006, Logan Capaldo wrote:

On Aug 30, 2006, at 1:52 PM, ara.t.howard@noaa.gov wrote:

regards.

-a
--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

Hi,

At Thu, 31 Aug 2006 03:02:14 +0900,
Logan Capaldo wrote in [ruby-talk:211561]:

I'd almost rather make the RCR for changing step rather than adding
Array.step. It's more general, and with 1.9 magic iterators I think
it would obviate the need to even have Array.step, e.g.: 1.step
(3).to_a. Make n.step { ... } work as well and make it walk backwards
if its from high to low.

Do you mean this?

  $ ruby -v -e 'p 1.step(5,2).to_a'
  ruby 1.9.0 (2006-08-29) [i686-linux]
  [1, 3, 5]

Pretty much, except possibly supporting Ara's additional requirements of 9.step.to_a and 1.step(-2).to_a #=> [1, 0, -1, -2]

···

On Aug 30, 2006, at 10:22 PM, nobu@ruby-lang.org wrote:

--
Nobu Nakada

indeed and agreed.

-a

···

On Thu, 31 Aug 2006, Logan Capaldo wrote:

On Aug 30, 2006, at 10:22 PM, nobu@ruby-lang.org wrote:

Hi,

At Thu, 31 Aug 2006 03:02:14 +0900,
Logan Capaldo wrote in [ruby-talk:211561]:

I'd almost rather make the RCR for changing step rather than adding
Array.step. It's more general, and with 1.9 magic iterators I think
it would obviate the need to even have Array.step, e.g.: 1.step
(3).to_a. Make n.step { ... } work as well and make it walk backwards
if its from high to low.

Do you mean this?

  $ ruby -v -e 'p 1.step(5,2).to_a'
  ruby 1.9.0 (2006-08-29) [i686-linux]
  [1, 3, 5]

Pretty much, except possibly supporting Ara's additional requirements of 9.step.to_a and 1.step(-2).to_a #=> [1, 0, -1, -2]

--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama