# What's the ruby way of grouping elements of an array?

**URL:** <https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741>\
**Category:** Ruby\
**Created:** [October 19, 2007, 9:01pm UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741 "2007-10-19T21:01:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [October 19, 2007, 9:01pm UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741/1 "2007-10-19T21:01:21Z")

</div>

Hi,

I thought this would be a common need but I couldn’t find a method.

Let’s say I have an array of objects.  
I want to group the elements by a property of objects.

people.group\_by do |person|  
person.age  
end

The above method should return an array of arrays grouped by age.

What’s the ruby way for this case?  
I think I can implement it but I am sure that a good way already exists.

Thanks.

Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [October 19, 2007, 9:18pm UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741/2 "2007-10-19T21:18:18Z")

</div>

On Oct 19, 2007, at 3:01 PM, Sam K. wrote:

> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).  
> ActiveSupport (part of Rails, but usable separately as a gem) does this:

[http://api.rubyonrails.org/classes/Enumerable.html#M001111](http://api.rubyonrails.org/classes/Enumerable.html#M001111)  
# File vendor/rails/activesupport/lib/active\_support/core\_ext/  
enumerable.rb, line 17  
17: def group\_by  
18: inject({}) do |groups, element|  
19: (groups[yield(element)] ||= []) \<\< element  
20: groups  
21: end  
22: end

This returns a hash of age=\>[people], but you could deal with that  
by .values or sorting or whatever makes the most sense for your  
application.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [October 19, 2007, 10:50pm UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741/3 "2007-10-19T22:50:22Z")

</div>

Sam K. wrote:

> The above method should return an array of arrays grouped by age.
> 
> What’s the ruby way for this case?  
> I think I can implement it but I am sure that a good way already exists.
> 
> Thanks.
> 
> Sam

If you require ‘action\_pack’ you get group\_by() for free

> > Array.new(20) {Kernel.rand(20)}.group\_by {|age| age \> 10}  
> > =\> {false=\>[9, 5, 3, 6, 0, 8, 3, 4, 9, 2, 0, 0, 10, 1], true=\>[15, 13,  
> > 18, 12, 13, 14]}
> 
> >

hth

ilan

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [October 20, 2007, 3:05am UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741/4 "2007-10-20T03:05:49Z")

</div>

On Oct 19, 2:01 pm, Sam K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The above method should return an array of arrays grouped by age.
> 
> What’s the ruby way for this case?  
> I think I can implement it but I am sure that a good way already exists.
> 
> Thanks.
> 
> Sam

It’s pretty simple.

class Array  
def group\_by  
h = Hash.new{ [] }  
each{|x|  
h[yield( x )] += [x]  
}  
h.values  
end  
end

p %w(a little while ago I heard the tittering of a mouse).  
group\_by{|s| s.size }

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [October 22, 2007, 5:22am UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741/5 "2007-10-22T05:22:00Z")

</div>

On Behalf Of Sam K.:

# people.group\_by do |person|

# person.age

# end

# The above method should return an array of arrays

# grouped by age. What’s the ruby way for this case?

# I think I can implement it but I am sure that a good

# way already exists.

as you’ve said (and as others have offered), you’ll have to implement it  
or use another lib/gem.

if you can wait for ruby2 (or use 1.9), the group\_by and symbol’s  
to\_proc is a good combi. eg,

> people.group\_by{|person| person.age}  
> …  
> or

> people.group\_by(& :age)  
> …  
> RUBY\_VERSION  
> =\> “1.9.0”

btw, group\_by returns hash of arrays

kind regards -botp

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [October 21, 2007, 1:18am UTC](https://www.ruby-forum.com/t/whats-the-ruby-way-of-grouping-elements-of-an-array/117741/6 "2007-10-21T01:18:06Z")

</div>

On Oct 19, 2007, at 9:05 PM, William J. wrote:

> > The above method should return an array of arrays grouped by age.  
> > h[yield( x )] += [x]  
> > }  
> > h.values  
> > end  
> > end

That’s good, but I think the following modification makes it a  
little better:

`
class Array
    def group_by
       h = Hash.new { |h, k| h[k] = [] }
       each { |item| h[yield(item)] << item }
       h.values
    end
end
`

Regards, Morton
