ruby 数组是否包含其他数组的值?

tmb3ates  于 2023-08-04  发布在  Ruby
关注(0)|答案(6)|浏览(144)

测试一个数组是否包含第二个数组中的任何元素的最有效的方法是什么?
下面的两个例子,试图回答问题foods是否包含cheeses中的任何元素:

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

字符串

nwsw7zdq

nwsw7zdq1#

(cheeses & foods).empty?

字符串
正如Marc-André Lafortune在评论中所说,&在线性时间内工作,而any? + include?将是二次的。对于较大的数据集,线性时间将更快。对于小数据集,any? + include?可能更快,如Lee Jarvis的答案所示-可能是因为&分配了一个新的Array,而另一个解决方案没有,并且作为一个简单的嵌套循环返回布尔值。

gopyfrb3

gopyfrb32#

如何使用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

字符串
基准脚本:

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


测试结果:

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)

6yt4nkrj

6yt4nkrj3#

您可以检查交叉点是否为空。

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

字符串

1tuwyuhd

1tuwyuhd4#

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) } } }  
  b.report("disjoint?") { N.times { FOODS.to_set.disjoint? CHEESES.to_set }}
end  
                      user     system      total        real
&, empty?         0.751068   0.000571   0.751639 (  0.752745)
any?, include?    0.408251   0.000133   0.408384 (  0.408438)
disjoint?        11.616006   0.014806  11.630812 ( 11.637300)

字符串

tvokkenx

tvokkenx5#

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

字符串

7vux5j2d

7vux5j2d6#

你可以使用intersect?,因为ruby 3.1**

foods.intersect?(cheeses)

字符串

相关问题