Alle domenica 8 luglio 2007, Shai Rosenfeld ha scritto:
> is there a nice clean method to do the following:
>
>
> a = Module.new(:att1 => 1, :att2 => "abc")
> b = Module.new(:att1 => 1, :att2 => "adfbc")
> c = Module.new(:att1 => 2, :att2 => "abcasdf")
> d = Module.new(:att1 => 1, :att2 => "ddddf")
> e = Module.new(:att1 => 2, :att2 => "ddddf")
> f = Module.new(:att1 => 3, :att2 => "ddddf")
>
> array = [a,b,c,d,e,f]
>
> # i want to take the 'array' var and make it into seperate arrays
> according to the att1 attribute, i.e, resulting in the example above to
>
> r1=[a,b,d]
> r2=[c,e]
> r3=[f]
>
> any nice way to do this?
>
> thx

You can do this (assuming that the objects in array have a method which 
returns the value of att1):

array.inject(Hash.new{|hash, key| hash[k] = []}) do |res, i|
  res[i.att1] << i
  res
end

This will return the following hash:
{
  1 => [a, b, d],
  2 => [c, e],
  3 => [f]
}

If you don't need to keep the items sorted, a more elegant way would be to use 
a Set instead of an array:

require 'set'

set = Set.new([a,b,c,d,e,f])
set.classify{|i| i.att1}

This returns an hash analogous to the previous one, but with arrays replaced 
by sets:

{
 1 => <Set:{a,b,d}>
 2 => <Set:{c,e}>
 3 => <Set:{f}>
}

You can then convert those Sets to arrays using their to_a method.

I hope this helps

Stefano