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

S

Sam Kong

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
 
R

Rob Biedenharn

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

ActiveSupport (part of Rails, but usable separately as a gem) does this:

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 Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
I

Ilan Berci

Sam said:
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
=> {false=>[9, 5, 3, 6, 0, 8, 3, 4, 9, 2, 0, 0, 10, 1], true=>[15, 13,
18, 12, 13, 14]}
hth

ilan
 
W

William James

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


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 }
 
M

Morton Goldberg

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.

It's pretty simple.

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

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

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

Regards, Morton
 
P

Peña, Botp

T24gQmVoYWxmIE9mIFNhbSBLb25nOg0KIyBwZW9wbGUuZ3JvdXBfYnkgZG8gfHBlcnNvbnwNCiMg
ICBwZXJzb24uYWdlDQojIGVuZA0KIyBUaGUgYWJvdmUgbWV0aG9kIHNob3VsZCByZXR1cm4gYW4g
YXJyYXkgb2YgYXJyYXlzIA0KIyBncm91cGVkIGJ5IGFnZS4gV2hhdCdzIHRoZSBydWJ5IHdheSBm
b3IgdGhpcyBjYXNlPw0KIyBJIHRoaW5rIEkgY2FuIGltcGxlbWVudCBpdCBidXQgSSBhbSBzdXJl
IHRoYXQgYSBnb29kIA0KIyB3YXkgYWxyZWFkeSBleGlzdHMuDQoNCmFzIHlvdSd2ZSBzYWlkIChh
bmQgYXMgb3RoZXJzIGhhdmUgb2ZmZXJlZCksIHlvdSdsbCBoYXZlIHRvIGltcGxlbWVudCBpdCBv
ciB1c2UgYW5vdGhlciBsaWIvZ2VtLg0KDQppZiB5b3UgY2FuIHdhaXQgZm9yIHJ1YnkyIChvciB1
c2UgMS45KSwgdGhlIGdyb3VwX2J5IGFuZCBzeW1ib2wncyB0b19wcm9jIGlzIGEgZ29vZCBjb21i
aS4gZWcsDQoNCj4gcGVvcGxlLmdyb3VwX2J5e3xwZXJzb258IHBlcnNvbi5hZ2V9DQouLi4NCm9y
DQoNCj4gcGVvcGxlLmdyb3VwX2J5KCYgOmFnZSkNCi4uLg0KPiBSVUJZX1ZFUlNJT04NCj0+ICIx
LjkuMCINCg0KYnR3LCBncm91cF9ieSByZXR1cm5zIGhhc2ggb2YgYXJyYXlzDQoNCmtpbmQgcmVn
YXJkcyAtYm90cA0K
 

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
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top