[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

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

Sam Kong

10/19/2007 7:01:00 PM

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
--
Posted via http://www.ruby-....

5 Answers

Rob Biedenharn

10/19/2007 7:17:00 PM

0


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

> 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
> --
> Posted via http://www.ruby-....

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

http://api.rubyonrails.org/classes/Enumerable.ht...
# 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://agileconsult...
Rob@AgileConsultingLLC.com




Ilan Berci

10/19/2007 8:50:00 PM

0

Sam Kong 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
--
Posted via http://www.ruby-....

William James

10/20/2007 1:03:00 AM

0

On Oct 19, 2:01 pm, Sam Kong <sam.s.k...@gmail.com> wrote:
> 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 }

Morton Goldberg

10/20/2007 11:17:00 PM

0

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

> On Oct 19, 2:01 pm, Sam Kong <sam.s.k...@gmail.com> wrote:
>> 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

Peña, Botp

10/22/2007 3:22:00 AM

0

On Behalf Of Sam Kong:
# 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