aboutsummaryrefslogtreecommitdiffstats
path: root/enum.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-20 08:39:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-20 08:39:12 +0000
commit0fbc72f5b4f699164907397fbfdebfd6fcf24130 (patch)
tree507dc795b1f2a1420947e6b6be193ad0bbd6c496 /enum.c
parent3e1bf6c9c488dd5c6643a3371d4489d2ce8c9e65 (diff)
downloadruby-0fbc72f5b4f699164907397fbfdebfd6fcf24130.tar.gz
enum.c: Enumerable#uniq
* enum.c (enum_uniq): new method Enumerable#uniq. [Feature #11090] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55709 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'enum.c')
-rw-r--r--enum.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/enum.c b/enum.c
index b62f7c3f37..fb1150a8a4 100644
--- a/enum.c
+++ b/enum.c
@@ -3793,6 +3793,40 @@ enum_sum(int argc, VALUE* argv, VALUE obj)
}
}
+static VALUE
+uniq_func(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ rb_hash_add_new_element(hash, i, i);
+ return Qnil;
+}
+
+static VALUE
+uniq_iter(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ rb_hash_add_new_element(hash, rb_yield_values2(argc, argv), i);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.uniq -> new_ary
+ * enum.uniq { |item| ... } -> new_ary
+ */
+
+static VALUE
+enum_uniq(VALUE obj)
+{
+ VALUE hash, ret;
+ rb_block_call_func *const func =
+ rb_block_given_p() ? uniq_iter : uniq_func;
+
+ hash = rb_obj_hide(rb_hash_new());
+ rb_block_call(obj, id_each, 0, 0, func, hash);
+ ret = rb_hash_values(hash);
+ rb_hash_clear(hash);
+ return ret;
+}
+
/*
* The <code>Enumerable</code> mixin provides collection classes with
* several traversal and searching methods, and with the ability to
@@ -3866,6 +3900,7 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, "slice_when", enum_slice_when, 0);
rb_define_method(rb_mEnumerable, "chunk_while", enum_chunk_while, 0);
rb_define_method(rb_mEnumerable, "sum", enum_sum, -1);
+ rb_define_method(rb_mEnumerable, "uniq", enum_uniq, 0);
id_next = rb_intern("next");
id_call = rb_intern("call");