On Sep 20, 4:47 pm, Matt Constantine <desig... / gmail.com> wrote:
> Hi all,
>
> I've run into a number of situations where I need to group an array
> while preserving order. For example, grouping the results of a database
> query without affecting their order or introducing extraneous logic in a
> view.
>
> I would like to know if there are any obvious problems or improvements
> to this solution:
>
> class Array
>   def partition_by(&b)
>     out=[]
>     self.inject([]) {|acc,e|
>       last = acc.pop
>       value = b.call(e)
>       out << {value=>[]} if last != value
>       out.last[value] << e
>       acc << value
>     }
>     out
>   end
> end
>
> So if I partition an array by element length, for example (contrived, I
> know):
> animals = %w(dog dog cat chicken chicken dog)
> animals.partition_by{|x| x.length}
>
> I get:
> [{3=>["dog", "dog", "cat"]}, {7=>["chicken", "chicken"]}, {3=>["dog"]}]

Without hashes:

class Array
  def group_by
    key = nil
    inject([]){|result,x|
      k = yield x
      if key == k  and result != []
        result[-1] << x
        next result
      end
      key = k
      result << [x]
    }
  end
end