# Simple array question

**URL:** <https://www.ruby-forum.com/t/simple-array-question/108863>\
**Category:** Ruby\
**Created:** [July 8, 2007, 11:14am UTC](https://www.ruby-forum.com/t/simple-array-question/108863 "2007-07-08T11:14:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 8, 2007, 11:14am UTC](https://www.ruby-forum.com/t/simple-array-question/108863/1 "2007-07-08T11:14:25Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 8, 2007, 11:44am UTC](https://www.ruby-forum.com/t/simple-array-question/108863/2 "2007-07-08T11:44:13Z")

</div>

Shai R. wrote:

> any nice way to do this?

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

---

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 8, 2007, 11:46am UTC](https://www.ruby-forum.com/t/simple-array-question/108863/3 "2007-07-08T11:46:14Z")

</div>

Alle domenica 8 luglio 2007, Shai R. ha scritto:

> array = [a,b,c,d,e,f]  
> 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

---

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 8, 2007, 11:53am UTC](https://www.ruby-forum.com/t/simple-array-question/108863/4 "2007-07-08T11:53:14Z")

</div>

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

> a = Module.new(:att1 =\> 1, :att2 =\> “abc”)

---

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 8, 2007, 11:49am UTC](https://www.ruby-forum.com/t/simple-array-question/108863/5 "2007-07-08T11:49:48Z")

</div>

Shai R. 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

---

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 9, 2007, 3:47pm UTC](https://www.ruby-forum.com/t/simple-array-question/108863/6 "2007-07-09T15:47:01Z")

</div>

i love this forum 🙂

thanks

---

<div class="post-metadata">

**Author:** ![harper](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@harper](https://www.ruby-forum.com/u/harper)\
**Post date:** [July 8, 2007, 11:54am UTC](https://www.ruby-forum.com/t/simple-array-question/108863/7 "2007-07-08T11:54:14Z")

</div>

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

> 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 would delegate the job to Set#classify.

– fxn
