数组包含来自另一个数组的任何值?

Pau*_*ves 151 ruby arrays

如果数组包含来自第二个数组的任何元素,那么测试最好,最优雅/最有效的方法是什么?

以下两个例子,试图回答这个问题,"食物"包含来自'奶酪'的任何元素:

cheeses = %w(chedder stilton brie mozzarella feta haloumi reblochon)
foods = %w(pizza feta foods bread biscuits yoghurt bacon)

puts cheeses.collect{|c| foods.include?(c)}.include?(true)

puts (cheeses - foods).size < cheeses.size
Run Code Online (Sandbox Code Playgroud)

Nak*_*lon 260

(cheeses & foods).empty?
Run Code Online (Sandbox Code Playgroud)

它也是如此,发布了injekt,但它已经用语言编译了动作.

正如Marc-AndréLafortune在评论中所说,&工作在线性时间,而any?+ include?将是二次方.对于更大的数据集,线性时间会更快.对于小数据集,any?+ include?可能更快,如Lee Jarvis的答案所示.

  • @Nakilon我也很困惑,为什么答案不是'(奶酪和食物).是什么?`不是OP的问题:如果有什么食物都是奶酪?在他的例子中,"feta"在两者中,所以结果应该是真的,对吧?那么为什么要在交叉路口检查`.empty?`? (3认同)
  • 当检查数组是否包含来自另一个数组的元素时,做(奶酪和食物)会不会更有意义.如果数组实际上包含任何相同的元素,则返回true值? (2认同)

Lee*_*vis 34

怎么样可以#任何?

>> cheeses = %w(chedder stilton brie mozzarella feta haloumi)
=> ["chedder", "stilton", "brie", "mozzarella", "feta", "haloumi"]
>> foods = %w(pizza feta foods bread biscuits yoghurt bacon)
=> ["pizza", "feta", "foods", "bread", "biscuits", "yoghurt", "bacon"]
>> foods.any? {|food| cheeses.include?(food) }
=> true
Run Code Online (Sandbox Code Playgroud)

基准脚本:

require "benchmark"
N = 1_000_000
puts "ruby version: #{RUBY_VERSION}"

CHEESES = %w(chedder stilton brie mozzarella feta haloumi).freeze
FOODS = %w(pizza feta foods bread biscuits yoghurt bacon).freeze

Benchmark.bm(15) do |b|
  b.report("&, empty?") { N.times { (FOODS & CHEESES).empty? } }
  b.report("any?, include?") { N.times { FOODS.any? {|food| CHEESES.include?(food) } } }
end
Run Code Online (Sandbox Code Playgroud)

结果:

ruby version: 2.1.9
                      user     system      total        real
&, empty?         1.170000   0.000000   1.170000 (  1.172507)
any?, include?    0.660000   0.000000   0.660000 (  0.666015)
Run Code Online (Sandbox Code Playgroud)

  • 该基准受所提到的特定示例所偏见,并不一定适用于更一般的情况。如果两个数组之间没有公共元素怎么办?如果每次通过时数组的顺序不同怎么办?如果羊乳酪出现在两个阵列的末端怎么办?正如Marc-André所述,集合交集是在线性时间内执行的,因此有意义的是,它在一般情况下具有更大的可伸缩性,而不是纯粹用来澄清问题的特定示例。 (4认同)

Sim*_*tti 22

您可以检查交叉路口是否为空.

cheeses = %w(chedder stilton brie mozzarella feta haloumi)
foods = %w(pizza feta foods bread biscuits yoghurt bacon)
foods & cheeses
=> ["feta"] 
(foods & cheeses).empty?
=> false
Run Code Online (Sandbox Code Playgroud)