Sam_Kong
(Sam Kong)
19 October 2007 19:01
1
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-forum.com/ .
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
Rob@AgileConsultingLLC.com
···
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-forum.com/\ .
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-forum.com/\ .
W_James
(W. James)
20 October 2007 01:05
4
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 }
···
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
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
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
···
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