[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]