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
} 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 Wed, Nov 29, 2006 at 10:55:37PM +0900, Gareth Adams 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
···
--
Bruno Michel
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 Schierbeck
···
On Wed, 2006-11-29 at 22:55 +0900, Gareth Adams wrote:
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
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
···
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
--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama
If you don't care about duplicates, just use Set#classify.
···
--
Lou.
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?
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
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 11/29/06, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
Why isn't there an Array#classify, which would return a hash of arrays,
preserving duplicates?
--
Lou.