如何确定一个数组是否包含另一个数组的所有元素

Mis*_*hko 170 ruby arrays ruby-on-rails

鉴于:

a1 = [5, 1, 6, 14, 2, 8]
Run Code Online (Sandbox Code Playgroud)

我想确定它是否包含以下所有元素:

a2 = [2, 6, 15]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,结果是false.

是否有任何内置的Ruby/Rails方法来识别这种数组包含?

实现此目的的一种方法是:

a2.index{ |x| !a1.include?(x) }.nil?
Run Code Online (Sandbox Code Playgroud)

有更好,更可读的方式吗?

Geo*_*Geo 295

a = [5, 1, 6, 14, 2, 8]
b = [2, 6, 15]

a - b
=> [5, 1, 14, 8]

b - a
=> [15]

(b - a).empty?
=> false
Run Code Online (Sandbox Code Playgroud)

  • 这是要走的路.它可能只是缩短为`(a2-a1).empty?` (59认同)
  • 这仅适用于集合的数组,不适用于具有重复项的数组 (7认同)
  • @Chris - 你可以尝试使用 Array#uniq 。以 Holger Just 的例子,它会是 `(a2.uniq - a1.uniq).empty?` (4认同)

Pab*_*dez 73

也许这更容易阅读:

a2.all? { |e| a1.include?(e) }
Run Code Online (Sandbox Code Playgroud)

您还可以使用数组交集:

(a1 & a2).size == a1.size
Run Code Online (Sandbox Code Playgroud)

注意size这里仅用于速度,你也可以(慢):

(a1 & a2) == a1
Run Code Online (Sandbox Code Playgroud)

但我想第一个更具可读性.这3个是普通的红宝石(不是铁轨).

  • 如果使用OP对a1和a2的定义,并且a1“包含”a2的所有元素,我认为这应该是 _ (a1 & a2).size == a2.size _ 因为a2是较小的数组,它应该包含所有较大数组中包含的元素(以获得“true”) - 因此,如果较小数组中的所有元素都存在于较大数组中,则两个数组的交集应与较小数组的长度相同。 (2认同)
  • 顺便说一句,Ruby 2.7 引入了一个新的 `intersection` 方法,因此我们现在可以使用更可读的方法 `(a1.intersection(a2)).size == a1.size` (2认同)

Hol*_*ust 53

这可以通过这样做来实现

(a2 & a1) == a2
Run Code Online (Sandbox Code Playgroud)

这将创建两个数组的交集,返回所有元素a2也在其中a1.如果结果相同a2,则可以确保包含所有元素a1.

这种方法只有在所有元素首先a2彼此不同时才有效.如果有双打,这种方法就失败了.Tempos的那个人当时仍然有效,所以我全心全意地推荐他的方法(也可能更快).

  • 如果交集在不同的顺序中具有相同的元素,则这将不起作用.我试图回答这个问题时发现了这个问题:http://stackoverflow.com/questions/12062970/array-permutations-and-comparisons-does-this-array-contain-any-of-these-arrays/ 12077841#12077841后来意识到很多聪明的人已经在这里做过了! (3认同)
  • 使用`length`方法会表现得更好 (2认同)

Con*_*ion 10

如果没有重复元素或您不关心它们,那么您可以使用Set类:

a1 = Set.new [5, 1, 6, 14, 2, 8]
a2 = Set.new [2, 6, 15]
a1.subset?(a2)
=> false
Run Code Online (Sandbox Code Playgroud)

在幕后使用

all? { |o| set.include?(o) }
Run Code Online (Sandbox Code Playgroud)