From: ara.t.howard@... Date: 2006-11-30T00:25:22+09:00 Subject: Re: Array#group_by On Thu, 30 Nov 2006, Bruno Michel wrote: > Gareth Adams a �crit : >> I posted this on the Rails list, but then I realised it would make more >> sense >> over here: >> >> ------- >> >> Just thought I'd share a function which has been really useful to me, for 2 >> reasons >> >> 1) It could easily help someone else >> 2) People might be able to make it work better or point out where it's not >> optimal >> >> class Array >> # Groups elements of an array based on a user-defined condition >> # # Each element from this array is passed to the block, and the >> returned value >> # determines the key under which it will be stored in the output hash >> # >> # If no block is given then the array indices will be used as the hash >> keys >> def group_by >> hsh = {} >> self.dup.each_with_index do |element, i| >> if block_given? >> key = yield element >> else >> key = i >> end >> hsh[key] ||= [] >> hsh[key] << element >> end >> hsh >> end >> end > > > Hi, > > thanks for the tip. I have q question with do you use a ".dup" on the line > self.dup.each_with_index do |element, i| ? Facets has a similar function > (partition_by), but don't use a ".dup" before iterating: > > http://facets.rubyforge.org/api/core/classes/Enumerable.html#M000526 i'm unlear how this adds to inject: harp:~ > cat a.rb words = %w( foo bar foobar ) grouped = words.inject Hash.new{|h,k| h[k] = []} do |h,k| h[k[0,1]] << k; h end p grouped harp:~ > ruby a.rb {"b"=>["bar"], "f"=>["foo", "foobar"]} which you can one-line if you wish: harp:~ > cat a.rb words = %w( foo bar foobar ) p words.inject({}){|h,k| (h[k[0,1]] ||= []) << k; h} harp:~ > ruby a.rb {"b"=>["bar"], "f"=>["foo", "foobar"]} regards. -a -- if you want others to be happy, practice compassion. if you want to be happy, practice compassion. -- the dalai lama