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

时间:2021-11-20 21:29:36

What's the best, most elegant/efficient way to test if an array contains any element from a second array?

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

Two examples below, attempting to answer the question does 'foods' contain any element from 'cheeses':

下面举两个例子,试图回答这个问题:“食物”是否含有“奶酪”中的任何成分?

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

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

puts (cheeses - foods).size < cheeses.size

4 个解决方案

#1


223  

(cheeses & foods).empty?

It does the same, what posted injekt, but it's already compiled actions in a language.

它也做同样的事情,发布injekt,但它已经用一种语言编译了动作。

As Marc-André Lafortune said in comments, & works in linear time while any? + include? will be quadratic. For larger sets of data, linear time will be faster. For small data sets, any? + include? may be faster as shown by Lee Jarvis' answer.

正如Marc-Andre Lafortune在评论中所言,&线性时间工作,还有吗?+包括什么?将二次。对于更大的数据集,线性时间将会更快。对于小数据集,有吗?+包括什么?李·贾维斯的回答可能会更快。

#2


20  

How about Enumerable#any?

可列举的#任何怎么样?

>> 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

Benchmark script:

基准脚本:

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

Result:

结果:

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)

#3


19  

You can check if the intersection is empty.

你可以检查十字路口是否空着。

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

#4


1  

Set.new(cheeses).disjoint? Set.new(foods)

#1


223  

(cheeses & foods).empty?

It does the same, what posted injekt, but it's already compiled actions in a language.

它也做同样的事情,发布injekt,但它已经用一种语言编译了动作。

As Marc-André Lafortune said in comments, & works in linear time while any? + include? will be quadratic. For larger sets of data, linear time will be faster. For small data sets, any? + include? may be faster as shown by Lee Jarvis' answer.

正如Marc-Andre Lafortune在评论中所言,&线性时间工作,还有吗?+包括什么?将二次。对于更大的数据集,线性时间将会更快。对于小数据集,有吗?+包括什么?李·贾维斯的回答可能会更快。

#2


20  

How about Enumerable#any?

可列举的#任何怎么样?

>> 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

Benchmark script:

基准脚本:

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

Result:

结果:

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)

#3


19  

You can check if the intersection is empty.

你可以检查十字路口是否空着。

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

#4


1  

Set.new(cheeses).disjoint? Set.new(foods)