如何确定数组是否包含在另一个数组中

时间:2017-04-03 00:28:25

标签: ruby

问题是,给定[1,2,3,4,5][2,4,5],以确定第二个数组中是否包含(第一个中的每个元素)。答案是肯定的。

最简洁有效的方法是:

arr2.reject { |e| arr1.include?(e) } .empty?

3 个答案:

答案 0 :(得分:4)

Array subtraction应该有效,如

(arr2 - arr1).empty?

方法描述:

  

返回一个新数组,它是原始数组的副本,删除任何数组   也出现在[第二个数组]中的项目。订单保留在   原始阵列。

     

它使用hash和eql来比较元素?提高效率的方法。

我不认为自己是效率方面的专家,但@Ryan在对his answer的评论中指出,它在规模上相当有效。

答案 1 :(得分:3)

坏的O(n²)单线程看起来像这样:

arr2.all? { |x| arr1.include? x }
arr2.all? &arr1.method(:include?)  # alternative

如果你的对象是可以清除的,你可以通过从第一个数组中设置一个来创建这个O(n):

require 'set'

arr2.all? &Set.new(arr1).method(:include?)

如果你的对象是完全的,像是,有序的,你可以使用排序和二分搜索使其成为O(n log n):

arr1.sort!
arr2.all? { |x| arr1.bsearch { |y| x <=> y } }

答案 2 :(得分:1)

正如@Ryan所说,你可以使用套装。在这种情况下,Set#subset?可供您使用,这是非常易读的(请注意从数组中定义集合的两种不同方式):

require 'set'

s1 = Set.new([1, 2, 3])
s2 = [1, 2].to_set
s3 = [1, 3].to_set
s4 = [1, 4].to_set

s1.subset? s1 #=> true
s2.subset? s1 #=> true
s3.subset? s1 #=> true
s4.subset? s1 #=> false

如果需要,还可以考虑使用Set#proper_subset

s1.proper_subset? s1 #=> false
s2.proper_subset? s1 #=> true

NB 一个集合不包含重复元素,例如Set.new([1,2,3,3]) #=> #<Set: {1, 2, 3}>