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

ruby-changes:58146

From: Prajjwal <ko1@a...>
Date: Mon, 7 Oct 2019 15:59:35 +0900 (JST)
Subject: [ruby-changes:58146] c8542ab484 (master): Add: Array#intersection method

https://git.ruby-lang.org/ruby.git/commit/?id=c8542ab484

From c8542ab484efb6ee0009cd081789d9a68f482483 Mon Sep 17 00:00:00 2001
From: Prajjwal Singh <sin@p...>
Date: Mon, 7 Oct 2019 10:42:29 +0530
Subject: Add: Array#intersection method


diff --git a/NEWS b/NEWS
index 958385f..d4e7e02 100644
--- a/NEWS
+++ b/NEWS
@@ -129,6 +129,12 @@ sufficient information, see the ChangeLog file or Redmine https://github.com/ruby/ruby/blob/trunk/NEWS#L129
 
 === Core classes updates (outstanding ones only)
 
+Array::
+
+  New method::
+
+    * Added Array#intersection. [Feature #16155]
+
 Complex::
 
   New method::
diff --git a/array.c b/array.c
index 9235bf2..341edb5 100644
--- a/array.c
+++ b/array.c
@@ -4668,6 +4668,36 @@ rb_ary_and(VALUE ary1, VALUE ary2) https://github.com/ruby/ruby/blob/trunk/array.c#L4668
     return ary3;
 }
 
+/*
+ *  call-seq:
+ *     ary.intersection(other_ary1, other_ary2, ...)      -> new_ary
+ *
+ *  Set Intersection --- Returns a new array containing unique elements common
+ *  to +self+ and <code>other_ary</code>s. Order is preserved from the original
+ *  array.
+ *
+ *  It compares elements using their #hash and #eql? methods for efficiency.
+ *
+ *     [ 1, 1, 3, 5 ].intersection([ 3, 2, 1 ])                    # => [ 1, 3 ]
+ *     [ "a", "b", "z" ].intersection([ "a", "b", "c" ], [ "b" ])  # => [ "b" ]
+ *     [ "a" ].intersection #=> [ "a" ]
+ *
+ *  See also Array#&.
+ */
+
+static VALUE
+rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
+{
+    VALUE result = rb_ary_dup(ary);
+    int i;
+
+    for (i = 0; i < argc; i++) {
+        result = rb_ary_and(result, argv[i]);
+    }
+
+    return result;
+}
+
 static int
 ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
 {
@@ -6928,6 +6958,7 @@ Init_Array(void) https://github.com/ruby/ruby/blob/trunk/array.c#L6958
     rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1);
     rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
     rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);
+    rb_define_method(rb_cArray, "intersection", rb_ary_intersection_multi, -1);
     rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
     rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
     rb_define_alias(rb_cArray,  "append", "push");
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 955a00a..6d730db 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -241,6 +241,23 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L241
     assert_equal(@cls[],     @cls[ 1, 2, 3 ]*64 & @cls[ 4, 5, 6 ]*64)
   end
 
+  def test_intersection
+    assert_equal(@cls[1, 2], @cls[1, 2, 3].intersection(@cls[1, 2]))
+    assert_equal(@cls[ ], @cls[1].intersection(@cls[ ]))
+    assert_equal(@cls[ ], @cls[ ].intersection(@cls[1]))
+    assert_equal(@cls[1], @cls[1, 2, 3].intersection(@cls[1, 2], @cls[1]))
+    assert_equal(@cls[ ], @cls[1, 2, 3].intersection(@cls[1, 2], @cls[3]))
+    assert_equal(@cls[ ], @cls[1, 2, 3].intersection(@cls[4, 5, 6]))
+  end
+
+  def test_intersection_big_array
+    assert_equal(@cls[1, 2], (@cls[1, 2, 3] * 64).intersection(@cls[1, 2] * 64))
+    assert_equal(@cls[ ], (@cls[1] * 64).intersection(@cls[ ]))
+    assert_equal(@cls[ ], @cls[ ].intersection(@cls[1] * 64))
+    assert_equal(@cls[1], (@cls[1, 2, 3] * 64).intersection((@cls[1, 2] * 64), (@cls[1] * 64)))
+    assert_equal(@cls[ ], (@cls[1, 2, 3] * 64).intersection(@cls[4, 5, 6] * 64))
+  end
+
   def test_MUL # '*'
     assert_equal(@cls[], @cls[]*3)
     assert_equal(@cls[1, 1, 1], @cls[1]*3)
-- 
cgit v0.10.2


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

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