ruby-changes:4465
From: ko1@a...
Date: Thu, 10 Apr 2008 20:12:42 +0900 (JST)
Subject: [ruby-changes:4465] knu - Ruby:r15956 (ruby_1_8): * enum.c (enum_first, enum_group_by): New methods:
knu 2008-04-10 20:12:08 +0900 (Thu, 10 Apr 2008)
New Revision: 15956
Modified files:
branches/ruby_1_8/ChangeLog
branches/ruby_1_8/NEWS
branches/ruby_1_8/enum.c
Log:
* enum.c (enum_first, enum_group_by): New methods:
Enumerable#first and #group_by; backported from 1.9.
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/enum.c?r1=15956&r2=15955&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?r1=15956&r2=15955&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/NEWS?r1=15956&r2=15955&diff_format=u
Index: ruby_1_8/NEWS
===================================================================
--- ruby_1_8/NEWS (revision 15955)
+++ ruby_1_8/NEWS (revision 15956)
@@ -54,6 +54,11 @@
New methods for various enumeration defined by the enumerator library.
+ * Enumerable#first
+ * Enumerable#group_by
+
+ New methods.
+
* Integer#ord implemented.
* Integer#odd? implemented.
* Integer#even? implemented.
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog (revision 15955)
+++ ruby_1_8/ChangeLog (revision 15956)
@@ -1,3 +1,8 @@
+Thu Apr 10 20:08:37 2008 Akinori MUSHA <knu@i...>
+
+ * enum.c (enum_first, enum_group_by): New methods:
+ Enumerable#first and #group_by; backported from 1.9.
+
Thu Apr 10 19:49:10 2008 Akinori MUSHA <knu@i...>
* enumerator.c (rb_eStopIteration), eval.c (rb_f_loop), ruby.h:
Index: ruby_1_8/enum.c
===================================================================
--- ruby_1_8/enum.c (revision 15955)
+++ ruby_1_8/enum.c (revision 15956)
@@ -386,8 +386,108 @@
return rb_assoc_new(ary[0], ary[1]);
}
+static VALUE
+group_by_i(i, hash)
+ VALUE i;
+ VALUE hash;
+{
+ VALUE group = rb_yield(i);
+ VALUE values;
+
+ values = rb_hash_aref(hash, group);
+ if (NIL_P(values)) {
+ values = rb_ary_new3(1, i);
+ rb_hash_aset(hash, group, values);
+ }
+ else {
+ rb_ary_push(values, i);
+ }
+ return Qnil;
+}
+
/*
* call-seq:
+ * enum.group_by {| obj | block } => a_hash
+ *
+ * Returns a hash, which keys are evaluated result from the
+ * block, and values are arrays of elements in <i>enum</i>
+ * corresponding to the key.
+ *
+ * (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
+ *
+ */
+
+static VALUE
+enum_group_by(obj)
+ VALUE obj;
+{
+ VALUE hash;
+
+ RETURN_ENUMERATOR(obj, 0, 0);
+
+ hash = rb_hash_new();
+ rb_block_call(obj, id_each, 0, 0, group_by_i, hash);
+
+ return hash;
+}
+
+static VALUE
+first_i(i, ary)
+ VALUE i;
+ VALUE *ary;
+{
+ if (NIL_P(ary[0])) {
+ ary[1] = i;
+ rb_iter_break();
+ }
+ else {
+ long n = NUM2LONG(ary[0]);
+
+ if (n <= 0) {
+ rb_iter_break();
+ }
+ rb_ary_push(ary[1], i);
+ n--;
+ ary[0] = INT2NUM(n);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.first -> obj or nil
+ * enum.first(n) -> an_array
+ *
+ * Returns the first element, or the first +n+ elements, of the enumerable.
+ * If the enumerable is empty, the first form returns <code>nil</code>, and the
+ * second form returns an empty array.
+ *
+ */
+
+static VALUE
+enum_first(argc, argv, obj)
+ int argc;
+ VALUE *argv;
+ VALUE obj;
+{
+ VALUE n, ary[2];
+
+ if (argc == 0) {
+ ary[0] = ary[1] = Qnil;
+ }
+ else {
+ rb_scan_args(argc, argv, "01", &n);
+ ary[0] = n;
+ ary[1] = rb_ary_new2(NUM2LONG(n));
+ }
+ rb_block_call(obj, id_each, 0, 0, first_i, (VALUE)ary);
+
+ return ary[1];
+}
+
+
+/*
+ * call-seq:
* enum.sort => array
* enum.sort {| a, b | block } => array
*
@@ -959,6 +1059,8 @@
rb_define_method(rb_mEnumerable,"map", enum_collect, 0);
rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
rb_define_method(rb_mEnumerable,"partition", enum_partition, 0);
+ rb_define_method(rb_mEnumerable,"group_by", enum_group_by, 0);
+ rb_define_method(rb_mEnumerable,"first", enum_first, -1);
rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
rb_define_method(rb_mEnumerable,"min", enum_min, 0);
--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/