[RCR] Enumerable#group_by

M

Michael Neumann

Hi,

I propose the addition of Enumerable#group_by which is a generalization
of Enumerable#partition.

module Enumerable
def group_by(store=Hash.new)
self.each do |elem|
group = yield elem
(store[group] ||= []) << elem
end
store
end
end

For example:

%w(This is a list of words).group_by {|word| word.size}

would result in:

{5=>["words"], 1=>["a"], 2=>["is", "of"], 4=>["This", "list"]}

Is this useful enough to include into Ruby?

Regards,

Michael
 
F

Florian Gross

Michael said:
Hi,
Moin!

%w(This is a list of words).group_by {|word| word.size}

would result in:

{5=>["words"], 1=>["a"], 2=>["is", "of"], 4=>["This", "list"]}

Is this useful enough to include into Ruby?

I have used this before when I needed to find files which have the same
content. Basically I did this: (Yes, I used exactly the same name and
almost the same logic as you. :))

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

And later:

files.group_by { |file| hash_file(file) }

So, yes, I think that this would make a great extension to the standard
Ruby.
Regards,
Michael

More regards,
Florian Gross
 
N

nobu.nokada

Hi,

At Wed, 26 May 2004 02:16:27 +0900,
Michael Neumann wrote in [ruby-talk:101382]:
I propose the addition of Enumerable#group_by which is a generalization
of Enumerable#partition.

I think it has been proposed also as Enumerable#classify. Here
is a patch I made at that time.


Index: enum.c
===================================================================
RCS file: /cvs/ruby/src/ruby/enum.c,v
retrieving revision 1.45
diff -U2 -p -d -r1.45 enum.c
--- enum.c 14 Apr 2004 04:06:24 -0000 1.45
+++ enum.c 21 Apr 2004 08:37:31 -0000
@@ -362,4 +362,37 @@ enum_partition(obj)
}

+static VALUE
+classify_i(i, hash)
+ VALUE i, hash;
+{
+ VALUE k = rb_yield(i);
+ VALUE ary = rb_hash_aref(hash, k);
+
+ if (NIL_P(ary)) {
+ rb_hash_aset(hash, k, ary = rb_ary_new());
+ }
+ rb_ary_push(ary, i);
+
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.classify {| x | block } => hash
+ *
+ * Returns a hash containing the items in <i>enum</i> classified.
+ */
+
+static VALUE
+enum_classify(obj)
+ VALUE obj;
+{
+ VALUE hash = rb_hash_new();
+
+ rb_iterate(rb_each, obj, classify_i, hash);
+
+ return hash;
+}
+
/*
* call-seq:
@@ -930,4 +963,5 @@ Init_Enumerable()
rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
rb_define_method(rb_mEnumerable,"partition", enum_partition, 0);
+ rb_define_method(rb_mEnumerable,"classify", enum_classify, 0);
rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top