summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-08-30 15:35:18 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-08-30 15:35:18 +0000
commit69ba229546f9ce43dfa6dd1a6544f7353e0ab847 (patch)
tree5de36a40994993875a23a943f6ddc373636ff5b8
parent74433fd300ff90e61086681fd1152d2da0d28171 (diff)
* 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
-rw-r--r--ChangeLog4
-rw-r--r--enum.c62
2 files changed, 66 insertions, 0 deletions
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 <keiju@ruby-lang.org>
* lib/irb/init.rb: bug fix. [ruby-dev: 26920]
+Tue Aug 30 16:13:00 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * enum.c (enum_count): new method. [ruby-dev:26895]
+
Tue Aug 30 12:45:15 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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
@@ -78,6 +78,67 @@ enum_grep(obj, pat)
}
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 <i>enum</i> for which equals to <i>item</i>.
+ * 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;
VALUE *memo;
@@ -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);