Array include any value from another array?

后端 未结 5 1972
青春惊慌失措
青春惊慌失措 2020-12-12 12:23

What\'s the most efficient way to test if an array contains any element from a second array?

Two examples below, attempting to answer the question does foods

相关标签:
5条回答
  • 2020-12-12 12:54

    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)
    
    0 讨论(0)
  • 2020-12-12 12:58
    (cheeses & foods).empty?
    

    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 -- probably because & allocates a new Array while another solution does not and works as a simple nested loop to return a boolean.

    0 讨论(0)
  • 2020-12-12 12:59

    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
    
    0 讨论(0)
  • 2020-12-12 13:05
    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)
    
    0 讨论(0)
  • 2020-12-12 13:18
    Set.new(cheeses).disjoint? Set.new(foods)
    
    0 讨论(0)
提交回复
热议问题