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/