# Simple array question

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

···

--
Posted via http://www.ruby-forum.com/.

Shai Rosenfeld wrote:

any nice way to do this?

array.inject({}) { |h,e| (h[e.att1] ||= []) << e; h }

···

--
Florian Frank

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

Shai Rosenfeld wrote:

is there a nice clean method to do the following:

# 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

I keep 'group_by' (stolen from ActiveSupport) on me for just such
situations:

module Enumerable
def group_by
inject({}) do |groups, element|
(groups[yield(element)] ||= []) << element
groups
end
end
end

array.group_by {|el| el.att1}

best,
Dan

···

--
Posted via http://www.ruby-forum.com/.

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

--
Posted via http://www.ruby-forum.com/.

···

El Jul 8, 2007, a las 11:28 AM, Shai Rosenfeld escribió:

I would delegate the job to Set#classify.

-- fxn

···

El Jul 8, 2007, a las 11:28 AM, Shai Rosenfeld escribió:

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?

i love this forum thanks

···

--
Posted via http://www.ruby-forum.com/.