I actually just need the following method there is no doubt about it;)
but the name which sprang into mind naturally "partition_by"
has a serious shortcoming, it is not POLS in the sense that
Enumerable#partition returns an array and Enumerable#partition_by
returns a hash.
module Enumerable
def partition_by &blk
result = Hash.new {|h,k| h[k] = [] }
each do | element |
result[ element ] << blk.call element
end
result
end
end
Any ideas for a nice different name?
Does Facet implement the above maybe?
A remark for my fellow fans of inject, the same code with inject
somehow does not feel right, I do not like to use inject with this
pattern
inject(...){ |acc,ele|
...
acc
}
# module Enumerable
# def partition_by &blk
# result = Hash.new {|h,k| h[k] = [] }
# each do | element |
# result[ element ] << blk.call element
# end
# result
# end
# end
# def partition_by &blk
# result = Hash.new {|h,k| h[k] = [] }
# each do | element |
# result[ element ] << blk.call element
# end
# result
# end
# end
module Enumerable
def group_by
result = Hash.new { |h, k| h[k] = Array.new }
self.each do |item|
group = yield(item)
result[group] << item
end
return result
end
end
This is the code of the post linked to above, as one can see it works,
not as mine above
but this natural way to write it is quite inefficient as the Facets
version shows. I have benchmarked them and to my surprise and that of
many others I guess the Facets implementation is almost twice as fast
- for many different keys at least
result = {}
each do | ele|
( result[ yield(ele) ] ||= [] ) << ele
end
result.
Does anybody have the faintest idea why Hash.new{|h,k| ... } is so inefficient?
BTW I am quite happy that #group_by is quasi a standard name for this.
On Fri, Apr 18, 2008 at 12:10 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:
>
> Which, I believe, first showed up in Rails sometime in 2006.
>
> --
> Rick DeNatale
>