比较Ruby中缺少元素的两个数组

时间:2016-05-06 17:59:23

标签: arrays ruby

我有两个拥有数千个元素的数组。我需要通过将它与另一个数组进行比较来找到一个数组中缺少的元素。有没有办法在不迭代整个数组的情况下获取缺失的元素?或者有什么比我正在做的更快?

以下是我现在使用的内容:

def find_missing(array1, array2)
    missing_elements = []
    array1.each { |e|  
        unless array2.include? e
            missing_elements << e
        end
    }

    return missing_elements
end

array1 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
array2 = [1, 2, 4, 5, 6, 7, 9]

puts find_missing(array1, array2)

4 个答案:

答案 0 :(得分:7)

您想要第一个数组的副本,但是要删除第二个数组中出现的所有元素?这是Array#-(数组差异)的作用:

array1 - array2
# => [10, 8, 3]

答案 1 :(得分:2)

您可以使用the difference operator

@irb(main):001:0> array1 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
@irb(main):002:0> array2 = [1, 2, 4, 5, 6, 7, 9]
=> [1, 2, 4, 5, 6, 7, 9]
@irb(main):003:0> array1 - array2
=> [10, 8, 3]

答案 2 :(得分:1)

我怀疑你可以用C语言编码array1 - array2Array#-,但你可能希望对其进行基准测试:

require 'set'

def use_sets(array1, array2)
  a1 = array1.uniq
  s2 = array2.to_set
  a1.reject { |e| s2.include?(e) }
end

加入..

require 'fruity'

def compare_em(array1, array2)
  compare do 
    _minus { array1 - array2 }
    _sets  { use_sets(array1, array2) }
  end
end

n = 100_000
array1 = (1..n).to_a.shuffle
array2 = (1..n-2).to_a.shuffle
compare_em(array1, array2)
  #_minus is faster than _sets by 2x ± 1.0

n = 1_000_000
array1 = (1..n).to_a.shuffle
array2 = (1..n-2).to_a.shuffle
compare_em(array1, array2)
  #_minus is faster than _sets by 2x ± 1.0

n = 100_000
array1 = (([1]*n).concat [1,2]).shuffle
array2 = [1]*n
compare_em(array1, array2)
  #_minus is faster than _sets by 5x ± 1.0

答案 3 :(得分:0)

要添加到最初接受的答案中,值得注意的是,以下解决方案将确保找到两个数组之间的差异,而与比较顺序无关。

array1 - array2 | array2 - array1
# => [10, 8, 3]

如果出于某种原因要以相反的方式比较两个数组,它将返回空数组并给出错觉。对于小型阵列,这可能是显而易见的,但对于大型阵列,则不是。

array2 - array1
# => []

不过需要注意的是,如果两个数组都存在差异,则会捕获它们之间的集体差异。

array1 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
array2 = [1, 2, 4, 5, 6, 7, 9, 11]

array1 - array2 | array2 - array1
# => [11, 10, 8, 3]