« Return to Thread: Proposal: Array#walker

Re: Proposal: Array#walker

by trans :: Rate this Message:

Reply to Author | View in Thread



On Nov 13, 7:37 pm, Wolfgang Nádasi-Donner <ed.oda...@...>
wrote:

> Good morning all together!
>
> I know it is very late for Ruby 1.9.1 proposals, but I have a very simple and
> easy suggestion. While writing a program to generate the Ruby program for some
> guessUTF test (border cases which should not success), I recognized, that it can
> be very helpful for several use cases to have a method Array#walker with the
> following Ruby implementation...
>
> class Array
>    def walker
>      l = self.length
>      l.times do |i|
>        yield self[0, i], self[i], self[i+1, l-i-1]
>      end
>    end
> end
>
> A simple usage example is...
>
> [1,2,3,4].walker{|pre,el,post|puts "#{pre.inspect}-#{el} - #{post.inspect}"}
>
> Output:
> []-1 - [2, 3, 4]
> [1]-2 - [3, 4]
> [1, 2]-3 - [4]
> [1, 2, 3]-4 - []
>
> What do you think about this (hopefully) minor change proposal?

Not so minor but this may interest you:

  # Iteration object.

  class It
    attr_reader :index, :value, :prior, :after
    def initialize(array)
      @array = array
      @index = 0
      @value = array[0]
      @prior = []
      @after = array[1..-1]
    end
    def first? ; @index == 0 ; end
    def last?  ; @index == @array.length ; end
    private
    def next_iteration
      @index += 1
      @prior << @value
      @value = @after.shift
    end
  end

  # Iterate over each element of array using an iteration object.

  def each_iteration
    if block_given?
      l = length
      it = It.new(self)
      l.times do |i|
        yield it
        it.send(:next_iteration)
      end
    else
      return Enumerable::Enumerator.new(self, :each_iteration)
    end
  end

Example:

irb(main):002:0> [:a,:b,:c].each_iteration{ |it|
irb(main):003:1*   p it.index, it.value, it.prior, it.after
irb(main):004:1> }

T.


 « Return to Thread: Proposal: Array#walker