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/