Массив включает какое-либо значение из другого массива? - PullRequest
145 голосов
/ 15 октября 2010

Какой самый эффективный способ проверить, содержит ли массив какой-либо элемент из второго массива?

Два приведенных ниже примера, пытаясь ответить на вопрос, содержит ли 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

Ответы [ 4 ]

249 голосов
/ 15 октября 2010
(cheeses & foods).empty?

Он делает то же самое, что опубликовал injekt, но это уже скомпилированные действия на языке.

Как сказал Марк-Андре Лафортун в комментариях, & работаетлинейное время, в то время как any? + include? будет квадратичным.Для больших наборов данных линейное время будет быстрее.Для небольших наборов данных any? + include? может быть быстрее, как показано в ответе Ли Джарвиса.

32 голосов
/ 15 октября 2010

Как насчет 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)
21 голосов
/ 15 октября 2010

Вы можете проверить, пусто ли пересечение.

cheeses = %w(chedder stilton brie mozzarella feta haloumi)
foods = %w(pizza feta foods bread biscuits yoghurt bacon)
foods & cheeses
=> ["feta"] 
(foods & cheeses).empty?
=> false
2 голосов
/ 27 сентября 2016
Set.new(cheeses).disjoint? Set.new(foods)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...