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

ruby-changes:43636

From: nobu <ko1@a...>
Date: Wed, 20 Jul 2016 17:39:17 +0900 (JST)
Subject: [ruby-changes:43636] nobu:r55709 (trunk): enum.c: Enumerable#uniq

nobu	2016-07-20 17:39:12 +0900 (Wed, 20 Jul 2016)

  New Revision: 55709

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55709

  Log:
    enum.c: Enumerable#uniq
    
    * enum.c (enum_uniq): new method Enumerable#uniq.
      [Feature #11090]

  Modified files:
    trunk/ChangeLog
    trunk/enum.c
    trunk/test/ruby/test_enum.rb
Index: enum.c
===================================================================
--- enum.c	(revision 55708)
+++ enum.c	(revision 55709)
@@ -3793,6 +3793,40 @@ enum_sum(int argc, VALUE* argv, VALUE ob https://github.com/ruby/ruby/blob/trunk/enum.c#L3793
     }
 }
 
+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) https://github.com/ruby/ruby/blob/trunk/enum.c#L3900
     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");
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55708)
+++ ChangeLog	(revision 55709)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Jul 20 17:39:11 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* enum.c (enum_uniq): new method Enumerable#uniq.
+	  [Feature #11090]
+
 Wed Jul 20 17:35:23 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* hash.c (rb_hash_add_new_element): add new element or do nothing
Index: test/ruby/test_enum.rb
===================================================================
--- test/ruby/test_enum.rb	(revision 55708)
+++ test/ruby/test_enum.rb	(revision 55709)
@@ -921,4 +921,19 @@ class TestEnumerable < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_enum.rb#L921
     assert_int_equal(2, (2..2).sum)
     assert_int_equal(42, (2...2).sum(42))
   end
+
+  def test_uniq
+    src = [1, 1, 1, 1, 2, 2, 3, 4, 5, 6]
+    assert_equal([1, 2, 3, 4, 5, 6], src.uniq.to_a)
+    olimpics = {
+      1896 => 'Athens',
+      1900 => 'Paris',
+      1904 => 'Chikago',
+      1906 => 'Athens',
+      1908 => 'Rome',
+    }
+    assert_equal([[1896, "Athens"], [1900, "Paris"], [1904, "Chikago"], [1908, "Rome"]],
+                 olimpics.uniq{|k,v| v})
+    assert_equal([1, 2, 3, 4, 5, 10], (1..100).uniq{|x| (x**2) % 10 }.first(6))
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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