在N个数组中找到共同的值

3

我有n个数组,想要确定这些数组中是否存在相同的值。如果我知道数组的数量,我可以这样做:

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

x = a & b & c

x == [2]

但是,如果您不知道数组的数量,则无法实现此操作。到目前为止,我想出了以下解决方案:

array_of_integers = [[1,2,3],[2,4,5]....]
values = []
array_of_integers.each_with_index do |array, index|
  values = if index.zero?
          array
        else
          values & array
        end
end
# `values` will be an array of common values

然而,这似乎不是很高效。有更好的方法吗?

我认为你的方法不可行。 - Sagar Pandya
@SagarPandya,你能解释一下为什么吗?到目前为止,它似乎对我编写的规格有效。但是Igor Drozdov的答案是一个更好的解决方案。 - mylescc
在您使用数组[[1,2,3],[2,4,5]]的示例中,我得到了values #=> [] - Sagar Pandya
1
@mylescc(1)您从未向“values”数组添加任何内容(2)由于“ids”是块作用域中的局部变量,因此在每次迭代开始时始终为“nil”。也许您的实际代码看起来不同。 - Stefan
啊,抱歉,是我的错。我从我的代码库中复制了内容,但忘记更改所有变量名称。我会更新我的示例的。谢谢! - mylescc
虽然使用reduce更受推荐,但可以使用递归:def recurse(arr); arr.size == 1 ? arr.first: arr.first & recurse(arr.drop(1)); end; recurse([a,b,c]) #=> [2] - Cary Swoveland
1个回答

10

但是,如果您不知道数组的数量,则无法实现此目标。

实际上,Enumerable#reduce可以帮助解决这个问题:

[[1,2,3], [2,4,5], [2,6,7]].reduce(&:&) # => [2]

&:& 看起来很有趣,但实际上它只是:

[[1,2,3], [2,4,5], [2,6,7]].reduce { |memo, el| memo & el } # => [2]

或者也可以像@Jagdeep建议的那样做:

[[1,2,3], [2,4,5], [2,6,7]].reduce(:&) # => [2]

7
这是一个Ruby代码的示例,使用 reduce 方法和 &: 操作符来计算数组 [[1,2,3], [2,4,5], [2,6,7]] 中所有子数组的交集。 - Jagdeep Singh
看一下 & 的源代码,似乎对于 [1, 2, 3] & []提前返回,但对于 [] & [1, 2, 3] 却没有。是否缺少了优化? - Stefan
1
@Stefan:看起来是这样。顺便说一下,JRuby对两者都有早期返回,而Rubinius对两者都没有 - Jörg W Mittag
1
@JörgWMittag,确实,我已经打开了一个拉取请求 - Stefan
@Stefan,如果reduce的接收器是一个数组,并且它的参数是:&,那么它应该在短路时停止运行。同样地,如果它的参数是:-,则对于相同的接收器,它也应该这样做。如果接收器是数字数组,当参数为:*:/时,它是否应该短路?也许我们可以想出其他例子。这可能就是为什么reduce根本不会短路的原因吗? - Cary Swoveland
1
@CarySwoveland 我认为reduce不应该做出任何这样的假设。而且很难(如果不是不可能)短路一个方法链。在我看来,可以在任意数量的数组上工作的数组操作方法(如交集和连接)应该是(优化的)类方法,或者至少应该有一个类方法变体,例如Array.concat(a1, a2, ...) - Stefan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接