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
- It could easily help someone else
- 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
On Wed, Nov 29, 2006 at 10:55:37PM +0900, Gareth A. wrote:
} 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
See
http://redcorundum.blogspot.com/2006/06/enumerablebucketby-and-uniqby-and.html
for a post of mine from June that covers that, and more.
–Greg
On Thu, 30 Nov 2006, Bruno M. wrote:
- It could easily help someone else
keys
end
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
Gareth A. a écrit :
optimal
self.dup.each_with_index do |element, i|
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
If you don’t care about duplicates, just use Set#classify.
Louis J Scoras wrote:
If you don’t care about duplicates, just use Set#classify.
Why isn’t there an Array#classify, which would return a hash of arrays,
preserving duplicates?
On 11/29/06, Joel VanderWerf [email protected] wrote:
Why isn’t there an Array#classify, which would return a hash of arrays,
preserving duplicates?
Beats me =) I’m not arguing against such a method; just pointing out
that there’s already something that might get the job done. A lot of
times people use arrays to represent sets without realizing it.
On Wed, 2006-11-29 at 22:55 +0900, Gareth A. wrote:
if block_given?
key = yield element
else
key = i
end
hsh[key] ||= []
hsh[key] << element
end
hsh
end
end
Here’s an improved version:
module Enumerable
def group_by
hsh = Hash.new{|hsh, key| hsh[key] = [] }
if block_given?
each{|obj| hsh[yield(obj)].push(obj) }
else
each_with_index{|obj, i| hsh[i].push(obj) }
end
hsh
end
end
Cheers,
Daniel S.
Louis J Scoras wrote:
On 11/29/06, Joel VanderWerf [email protected] wrote:
Why isn’t there an Array#classify, which would return a hash of arrays,
preserving duplicates?
Beats me =) I’m not arguing against such a method; just pointing out
that there’s already something that might get the job done. A lot of
times people use arrays to represent sets without realizing it.
I wasn’t arguing either. I had forgotten about the useful Set#classify,
and thought why not have one for Array too? I can’t see any theoretical
reason not to.