问题是,给定[1,2,3,4,5]
和[2,4,5]
,以确定第二个数组中是否包含(第一个中的每个元素)。答案是肯定的。
最简洁有效的方法是:
arr2.reject { |e| arr1.include?(e) } .empty?
答案 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}>