41

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

谢谢。

4

5 回答 5

95

设置相交它们:

a1 & a2

这是一个例子:

> a1 = [ 'foo', 'bar' ]
> a2 = [ 'bar', 'baz' ]
> a1 & a2
=> ["bar"]
> !(a1 & a2).empty? # Returns true if there are any elements in common
=> true
于 2010-04-08T22:32:25.227 回答
8

有什么共同的价值吗?您可以使用交集运算符:&

[ 1, 1, 3, 5 ] & [ 1, 2, 3 ]   #=> [ 1, 3 ]

但是,如果您正在寻找一个完整的交集(带有重复项),那么问题会更加复杂,这里已经存在堆栈溢出:如何返回具有重复元素的 Ruby 数组交集?(骰子系数中的二元组问题)

或定义“real_intersection”并验证以下测试的快速片段

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
于 2010-04-08T22:37:07.403 回答
6

使用交集看起来不错,但效率低下。我会用“任何?” 在第一个数组上(以便在第二个数组中找到一个元素时停止迭代)。此外,在第二个数组上使用 Set 将使成员资格检查速度更快。IE:

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
于 2015-11-09T18:40:51.827 回答
1

数组#intersect? (红宝石 3​​.1+)

从 Ruby 3.1 开始,有一个新Array#intersect?方法,它检查两个数组是否至少有一个共同的元素。

这是一个例子:

a = [1, 2, 3]
b = [3, 4, 5]
c = [7, 8, 9]

# 3 is the common element
a.intersect?(b)
# => true

# No common elements
a.intersect?(c)
# => false

此外,Array#intersect?它可以比替代方案快得多,因为它避免创建中间数组,一旦找到公共元素就返回 true,它是用 C 实现的。

资料来源:

于 2021-05-11T19:13:50.713 回答
0

尝试这个

a1 = [ 'foo', 'bar' ] 
a2 = [ 'bar', 'baz' ]
a1-a2 != a1
true
于 2017-04-18T13:08:16.797 回答