simple array question

S

Shai Rosenfeld

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
 
S

Stefano Crocco

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
 
D

Daniel Lucraft

Shai said:
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
 
X

Xavier Noria

El Jul 8, 2007, a las 11:28 AM, Shai Rosenfeld escribi=F3:
a =3D Module.new:)att1 =3D> 1, :att2 =3D> "abc")
b =3D Module.new:)att1 =3D> 1, :att2 =3D> "adfbc")
c =3D Module.new:)att1 =3D> 2, :att2 =3D> "abcasdf")
d =3D Module.new:)att1 =3D> 1, :att2 =3D> "ddddf")
e =3D Module.new:)att1 =3D> 2, :att2 =3D> "ddddf")
f =3D Module.new:)att1 =3D> 3, :att2 =3D> "ddddf")

array =3D [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 =20
above to

r1=3D[a,b,d]
r2=3D[c,e]
r3=3D[f]

any nice way to do this?

I would delegate the job to Set#classify.

-- fxn
 

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

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,311
Members
47,983
Latest member
Derek9890

Latest Threads

Top