From 83d3eb48d649eed93db3c47a0f9827c5c6281645 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Tue, 2 Jul 2019 12:31:00 +0100 Subject: [PATCH 1/3] Add Array#overlaps? This is semantically equivalent to (ary1 & ary2).any?, but more efficient --- array.c | 52 +++++++++++++++++++++++++++++++++++++++++ test/ruby/test_array.rb | 14 +++++++++++ 2 files changed, 66 insertions(+) diff --git a/array.c b/array.c index d441de84e42d..fdb0a7f42966 100644 --- a/array.c +++ b/array.c @@ -4631,6 +4631,56 @@ rb_ary_and(VALUE ary1, VALUE ary2) return ary3; } +/* + * call-seq: + * ary.overlaps?(ary2) -> true or false + * + * Returns +true+ if the intersection of +ary+ and +ary2+ is non empty, else returns false. + * + * This is equivalent to (ary & ary2).any? + * + * [ "a", "b", "c" ].overlaps?( [ "c", "d", "a" ] ) #=> true + * [ "a" ].overlaps?( ["e", "b"] ) #=> false + * [ "a" ].overlaps?( [] ) #=> false + * + * See also Array#&. + */ + +static VALUE +rb_ary_and_p(VALUE ary1, VALUE ary2) +{ + VALUE hash, result, v; + st_data_t vv; + long i; + + ary2 = to_ary(ary2); + if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse; + + if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) { + for (i=0; i Date: Tue, 2 Jul 2019 16:04:45 +0100 Subject: [PATCH 2/3] rename overlaps? -> overlap? This is more consistent with other predicate methods (include?, cover?) --- array.c | 10 +++++----- test/ruby/test_array.rb | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/array.c b/array.c index fdb0a7f42966..759db9992fa8 100644 --- a/array.c +++ b/array.c @@ -4633,15 +4633,15 @@ rb_ary_and(VALUE ary1, VALUE ary2) /* * call-seq: - * ary.overlaps?(ary2) -> true or false + * ary.overlap?(ary2) -> true or false * * Returns +true+ if the intersection of +ary+ and +ary2+ is non empty, else returns false. * * This is equivalent to (ary & ary2).any? * - * [ "a", "b", "c" ].overlaps?( [ "c", "d", "a" ] ) #=> true - * [ "a" ].overlaps?( ["e", "b"] ) #=> false - * [ "a" ].overlaps?( [] ) #=> false + * [ "a", "b", "c" ].overlap?( [ "c", "d", "a" ] ) #=> true + * [ "a" ].overlap?( ["e", "b"] ) #=> false + * [ "a" ].overlap?( [] ) #=> false * * See also Array#&. */ @@ -6948,7 +6948,7 @@ Init_Array(void) rb_define_method(rb_cArray, "-", rb_ary_diff, 1); rb_define_method(rb_cArray, "&", rb_ary_and, 1); - rb_define_method(rb_cArray, "overlaps?", rb_ary_and_p, 1); + rb_define_method(rb_cArray, "overlap?", rb_ary_and_p, 1); rb_define_method(rb_cArray, "|", rb_ary_or, 1); diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 742979c09c09..9e1ed640cb77 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -241,18 +241,18 @@ def test_AND_big_array # '&' assert_equal(@cls[], @cls[ 1, 2, 3 ]*64 & @cls[ 4, 5, 6 ]*64) end - def test_overlaps - assert_equal(true, @cls[ 1, 1, 3, 5 ].overlaps?( @cls[ 1, 2, 3 ])) - assert_equal(false, @cls[ 1, 1, 3, 5 ].overlaps?( @cls[ ])) - assert_equal(false, @cls[ ].overlaps?( @cls[ 1, 2, 3 ])) - assert_equal(false, @cls[ 1, 2, 3 ].overlaps?( @cls[ 4, 5, 6 ])) - end - - def test_overlaps_big_array - assert_equal(true, (@cls[ 1, 1, 3, 5 ]*64).overlaps?(@cls[ 1, 2, 3 ]*64)) - assert_equal(false, (@cls[ 1, 1, 3, 5 ]*64).overlaps?(@cls[ ])) - assert_equal(false, (@cls[ ]).overlaps?(@cls[ 1, 2, 3 ]*64)) - assert_equal(false, (@cls[ 1, 2, 3 ]*64).overlaps?(@cls[ 4, 5, 6 ]*64)) + def test_overlap + assert_equal(true, @cls[ 1, 1, 3, 5 ].overlap?( @cls[ 1, 2, 3 ])) + assert_equal(false, @cls[ 1, 1, 3, 5 ].overlap?( @cls[ ])) + assert_equal(false, @cls[ ].overlap?( @cls[ 1, 2, 3 ])) + assert_equal(false, @cls[ 1, 2, 3 ].overlap?( @cls[ 4, 5, 6 ])) + end + + def test_overlap_big_array + assert_equal(true, (@cls[ 1, 1, 3, 5 ]*64).overlap?(@cls[ 1, 2, 3 ]*64)) + assert_equal(false, (@cls[ 1, 1, 3, 5 ]*64).overlap?(@cls[ ])) + assert_equal(false, (@cls[ ]).overlap?(@cls[ 1, 2, 3 ]*64)) + assert_equal(false, (@cls[ 1, 2, 3 ]*64).overlap?(@cls[ 4, 5, 6 ]*64)) end def test_MUL # '*' From b51b7fdeeeee559092f04624c891e79036a5cba8 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Tue, 2 Jul 2019 21:59:03 +0100 Subject: [PATCH 3/3] Array#overlap?: fix documentation --- array.c | 2 +- test/ruby/test_array.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/array.c b/array.c index 759db9992fa8..a91a31be3b52 100644 --- a/array.c +++ b/array.c @@ -4637,7 +4637,7 @@ rb_ary_and(VALUE ary1, VALUE ary2) * * Returns +true+ if the intersection of +ary+ and +ary2+ is non empty, else returns false. * - * This is equivalent to (ary & ary2).any? + * This is equivalent to !(ary & ary2).empty? * * [ "a", "b", "c" ].overlap?( [ "c", "d", "a" ] ) #=> true * [ "a" ].overlap?( ["e", "b"] ) #=> false diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 9e1ed640cb77..94e9444731dc 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -242,6 +242,7 @@ def test_AND_big_array # '&' end def test_overlap + assert_equal(true, @cls[ nil ].overlap?( @cls[ nil ])) assert_equal(true, @cls[ 1, 1, 3, 5 ].overlap?( @cls[ 1, 2, 3 ])) assert_equal(false, @cls[ 1, 1, 3, 5 ].overlap?( @cls[ ])) assert_equal(false, @cls[ ].overlap?( @cls[ 1, 2, 3 ]))