Quick way to split up an array of objects into groups?

M

Max Williams

I have a collection of objects, which i want to separate into groups
based on a particular property (to be specific, two attributes - that is
if obj.foo and obj.bar are both the same for two objects they go into an
array together). Not every object has a duplicate, but most of them do.
So, i'd end up with an array, where each member is another array, with
the subarrays holding either 1 or 2 (or maybe more) objects that match
on foo and bar.

Can anyone tell me a nice and simple way of doing this?

thanks
max
 
X

Xavier Noria

I have a collection of objects, which i want to separate into groups
based on a particular property (to be specific, two attributes -
that is
if obj.foo and obj.bar are both the same for two objects they go
into an
array together). Not every object has a duplicate, but most of them
do.
So, i'd end up with an array, where each member is another array, with
the subarrays holding either 1 or 2 (or maybe more) objects that match
on foo and bar.

Can anyone tell me a nice and simple way of doing this?

Enumerable#parition or Set#classify might help.

-- fxn
 
M

Max Williams

Xavier said:
Enumerable#parition or Set#classify might help.

-- fxn

hmmm...i couldn't work out how to make it easier with either of those.
I ended up doing this, which isn't very clever but it did seem to work.

groups = []
vals = collection.collect{|obj| [obj.val1, obj.val2]}.uniq!
for val in vals
groups << collection.select{|obj| obj.val1 == val[0] && obj.val2 =
val[1]
end
 
R

Rick DeNatale

Xavier said:
Enumerable#parition or Set#classify might help.

-- fxn

hmmm...i couldn't work out how to make it easier with either of those.
I ended up doing this, which isn't very clever but it did seem to work.

groups = []
vals = collection.collect{|obj| [obj.val1, obj.val2]}.uniq!
for val in vals
groups << collection.select{|obj| obj.val1 == val[0] && obj.val2 =
val[1]
end

The activesupport gem, which is part of Rails, but can be used
separately, adds an Enumerable#group_by method which does pretty much
what you are asking for if I understand correctly.
 
X

Xavier Noria

Xavier said:
Enumerable#parition or Set#classify might help.

-- fxn

hmmm...i couldn't work out how to make it easier with either of those.
I ended up doing this, which isn't very clever but it did seem to
work.

groups = []
vals = collection.collect{|obj| [obj.val1, obj.val2]}.uniq!
for val in vals
groups << collection.select{|obj| obj.val1 == val[0] && obj.val2 =
val[1]

Note there is an assignment instead of an equals operator there.

Yes, I think that's equivalent to

collection.to_set.classify {|x| [x.foo, x.bar]}.values

plus perhaps a map to_a.

-- fxn
 
M

Max Williams

Xavier said:
Note there is an assignment instead of an equals operator there.

Yes, I think that's equivalent to

collection.to_set.classify {|x| [x.foo, x.bar]}.values

plus perhaps a map to_a.

-- fxn

That's not really my code, it's a paraphrased version for clarity :)
Cheers for the tip about to_set.classify though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top