如何检查Ruby数组是否包含多个值中的一个?

如何检查Ruby数组是否包含多个值中的一个?,ruby,string,arrays,intersect,Ruby,String,Arrays,Intersect,我有两个Ruby数组,我需要看看它们是否有共同的值。我可以循环遍历一个数组中的每个值,并在另一个数组中包含?(),但我相信有更好的方法。这是怎么一回事?(两个数组都包含字符串。) 谢谢。他们: 下面是一个例子: > a1 = [ 'foo', 'bar' ] > a2 = [ 'bar', 'baz' ] > a1 & a2 => ["bar"] > !(a1 & a2).empty? # Returns true if there are any

我有两个Ruby数组,我需要看看它们是否有共同的值。我可以循环遍历一个数组中的每个值,并在另一个数组中包含?(),但我相信有更好的方法。这是怎么一回事?(两个数组都包含字符串。)

谢谢。

他们:

下面是一个例子:

> a1 = [ 'foo', 'bar' ]
> a2 = [ 'bar', 'baz' ]
> a1 & a2
=> ["bar"]
> !(a1 & a2).empty? # Returns true if there are any elements in common
=> true

有共同的价值吗?可以使用“交点”操作符:

但是,如果您正在寻找一个完整的交叉点(使用重复的交叉点),则问题更为复杂,这里已经存在堆栈溢出:

或定义“真实交叉点”并验证以下测试的quick

class ArrayIntersectionTests < Test::Unit::TestCase    
  def test_real_array_intersection
    assert_equal [2], [2, 2, 2, 3, 7, 13, 49] & [2, 2, 2, 5, 11, 107]
    assert_equal [2, 2, 2], [2, 2, 2, 3, 7, 13, 49].real_intersection([2, 2, 2, 5, 11, 107])
    assert_equal ['a', 'c'], ['a', 'b', 'a', 'c'] & ['a', 'c', 'a', 'd']
    assert_equal ['a', 'a', 'c'], ['a', 'b', 'a', 'c'].real_intersection(['a', 'c', 'a', 'd'])
  end
end
class ArrayIntersectionTests
使用交叉口看起来不错,但效率很低。我会在第一个数组中使用“any?”(这样当在第二个数组中找到一个元素时,迭代就会停止)。另外,在第二个数组上使用集合可以快速进行成员身份检查。i、 e:

a = [:a, :b, :c, :d]
b = Set.new([:c, :d, :e, :f])
c = [:a, :b, :g, :h]

# Do a and b have at least a common value?
a.any? {|item| b.include? item}
# true

# Do c and b have at least a common value?
c.any? {|item| b.include? item}
#false
试试这个

a1 = [ 'foo', 'bar' ] 
a2 = [ 'bar', 'baz' ]
a1-a2 != a1
true
数组#相交?(Ruby 3.1+) 从Ruby 3.1开始,有一个新的
数组#intersect?
方法, 它检查两个数组是否至少有一个共同元素

以下是一个例子:

> a1 = [ 'foo', 'bar' ]
> a2 = [ 'bar', 'baz' ]
> a1 & a2
=> ["bar"]
> !(a1 & a2).empty? # Returns true if there are any elements in common
=> true
a=[1,2,3]
b=[3,4,5]
c=[7,8,9]
#3是公共元素
a、 相交?(b)
#=>正确
#没有共同点
a、 相交?(c)
#=>错误
另外,
Array#intersect?
可以比备选方案快得多,因为它避免创建中间数组,一旦找到公共元素就会返回true,它是用C实现的

来源:


你在乎它有什么共同点吗?不。我只想知道这两个元素是否有任何共同点。好吧,OP想要“检查”,所以布尔结果更适合:!(a1和a2)。空的?我会和(a1和a2)一起去。有吗?而不是(a1和a2).空?@rilla
any?
在这种情况下有效,但在处理
false
nil
值时无效:
[nil,false]。any?#=>false
。有没有更整洁的方法来执行
!(a1和a2).空?
?@DavidWest yes,
(a1和a2).当前?
。基准测试表明,根据简单的值与对象属性比较,这比(更美观的)集合相交方法快1.5-2倍。使用
any?
而不是
empty?
设置交叉点,正如上面一条评论中所建议的,略有不同,但没有改变结果。(严格考虑性能,并且正如预期的那样,因为
any?
在第一场比赛中退出。)
a1 = [ 'foo', 'bar' ] 
a2 = [ 'bar', 'baz' ]
a1-a2 != a1
true