1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Add Array#intersect?

This commit is contained in:
Travis Hunter 2018-10-03 15:19:36 -04:00 committed by Nobuyoshi Nakada
parent 97cee1cba6
commit 55d91a096a
Notes: git 2021-04-16 16:07:05 +09:00
2 changed files with 69 additions and 0 deletions

56
array.c
View file

@ -5567,6 +5567,61 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
return ary_union;
}
/*
* call-seq:
* ary.intersect?(other_ary) -> true or false
*
* Returns +true+ if the array and +other_ary+ have at least one element in
* common, otherwise returns +false+.
*
* a = [ 1, 2, 3 ]
* b = [ 3, 4, 5 ]
* c = [ 5, 6, 7 ]
* a.intersect?(b) #=> true
* a.intersect?(c) #=> false
*/
static VALUE
rb_ary_intersect_p(VALUE ary1, VALUE ary2)
{
VALUE hash, v, result, shorter, longer;
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<RARRAY_LEN(ary1); i++) {
v = RARRAY_AREF(ary1, i);
if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;
}
return Qfalse;
}
shorter = ary1;
longer = ary2;
if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
longer = ary1;
shorter = ary2;
}
hash = ary_make_hash(shorter);
result = Qfalse;
for (i=0; i<RARRAY_LEN(longer); i++) {
v = RARRAY_AREF(longer, i);
vv = (st_data_t)v;
if (rb_hash_stlike_lookup(hash, vv, 0)) {
result = Qtrue;
break;
}
}
ary_recycle_hash(hash);
return result;
}
static VALUE
ary_max_generic(VALUE ary, long i, VALUE vmax)
{
@ -8295,6 +8350,7 @@ Init_Array(void)
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, "intersect?", rb_ary_intersect_p, 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");

View file

@ -1100,6 +1100,19 @@ class TestArray < Test::Unit::TestCase
assert_not_include(a, [1,2])
end
def test_intersect?
a = @cls[ 1, 2, 3]
assert_send([a, :intersect?, [3]])
assert_not_send([a, :intersect?, [4]])
assert_not_send([a, :intersect?, []])
end
def test_intersect_big_array
assert_send([@cls[ 1, 4, 5 ]*64, :intersect?, @cls[ 1, 2, 3 ]*64])
assert_not_send([@cls[ 1, 2, 3 ]*64, :intersect?, @cls[ 4, 5, 6 ]*64])
assert_not_send([@cls[], :intersect?, @cls[ 1, 2, 3 ]*64])
end
def test_index
a = @cls[ 'cat', 99, /a/, 99, @cls[ 1, 2, 3] ]
assert_equal(0, a.index('cat'))