From 69ba229546f9ce43dfa6dd1a6544f7353e0ab847 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 30 Aug 2005 15:35:18 +0000 Subject: [PATCH] * enum.c (enum_count): new method. [ruby-dev:26895] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9054 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++++ enum.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/ChangeLog b/ChangeLog index f5482d382e..13d6d2d119 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,10 @@ Tue Aug 30 16:19:40 2005 Keiju Ishitsuka * lib/irb/init.rb: bug fix. [ruby-dev: 26920] +Tue Aug 30 16:13:00 2005 Yukihiro Matsumoto + + * enum.c (enum_count): new method. [ruby-dev:26895] + Tue Aug 30 12:45:15 2005 Yukihiro Matsumoto * eval.c (rb_f_send): do not call private methods if the receiver diff --git a/enum.c b/enum.c index c0c08e9808..2e8d71f604 100644 --- a/enum.c +++ b/enum.c @@ -77,6 +77,67 @@ enum_grep(obj, pat) return ary; } +static VALUE +count_i(i, arg) + VALUE i, *arg; +{ + if (rb_equal(i, arg[0])) { + arg[1]++; + } + return Qnil; +} + +static VALUE +count_iter_i(i, n) + VALUE i; + long *n; +{ + if (RTEST(rb_yield(i))) { + (*n)++; + } + return Qnil; +} + +/* + * call-seq: + * enum.count(item) => int + * enum.count {| obj | block } => int + * + * Returns the number of items in enum for which equals to item. + * If a block is given, counts the number of elements yielding a true value. + * + * ary = [1, 2, 4, 2] + * ary.count(2) # => 2 + * ary.count{|x|x%2==0} # => 3 + * + */ + +static VALUE +enum_count(argc, argv, obj) + int argc; + VALUE* argv; + VALUE obj; +{ + if (argc == 1) { + VALUE item, args[2]; + + if (rb_block_given_p()) { + rb_warn("given block not used"); + } + rb_scan_args(argc, argv, "1", &item); + args[0] = item; + args[1] = 0; + rb_iterate(rb_each, obj, count_i, (VALUE)&args); + return INT2NUM(args[1]); + } + else { + long n = 0; + + rb_iterate(rb_each, obj, count_iter_i, (VALUE)&n); + return INT2NUM(n); + } +} + static VALUE find_i(i, memo) VALUE i; @@ -995,6 +1056,7 @@ Init_Enumerable() rb_define_method(rb_mEnumerable,"sort", enum_sort, 0); rb_define_method(rb_mEnumerable,"sort_by", enum_sort_by, 0); rb_define_method(rb_mEnumerable,"grep", enum_grep, 1); + rb_define_method(rb_mEnumerable,"count", enum_count, -1); rb_define_method(rb_mEnumerable,"find", enum_find, -1); rb_define_method(rb_mEnumerable,"detect", enum_find, -1); rb_define_method(rb_mEnumerable,"find_all", enum_find_all, 0);