Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if one array contains all elements of another array

Tags:

arrays

ruby

I need to tell if an array contains all of the elements of another array with duplicates.

[1,2,3].contains_all? [1,2]   #=> true
[1,2,3].contains_all? [1,2,2] #=> false (this is where (a1-a2).empty? fails)
[2,1,2,3].contains_all? [1,2,2] #=> true

So the first array must contain as many or equal of the number of each unique element in the second array.

This question answers it for those using an array as a set, but I need to control for duplicates.

Update: Benchmarks

On Ruby 1.9.3p194

def bench
  puts Benchmark.measure {
    10000.times do
      [1,2,3].contains_all? [1,2]
      [1,2,3].contains_all? [1,2,2]
      [2,1,2,3].contains_all? [1,2,2]
    end
  }
end

Results in:

Rohit   0.100000   0.000000   0.100000 (  0.104486)
Chris   0.040000   0.000000   0.040000 (  0.040178)
Sergio  0.160000   0.020000   0.180000 (  0.173940)
sawa    0.030000   0.000000   0.030000 (  0.032393)

Update 2: Larger Arrays

@a1 = (1..10000).to_a
@a2 = (1..1000).to_a
@a3 = (1..2000).to_a

def bench
  puts Benchmark.measure {
    1000.times do
      @a1.contains_all? @a2
      @a1.contains_all? @a3
      @a3.contains_all? @a2
    end
  }
end

Results in:

Rohit    9.750000   0.410000  10.160000 ( 10.158182)
Chris   10.250000   0.180000  10.430000 ( 10.433797)
Sergio  14.570000   0.070000  14.640000 ( 14.637870)
sawa     3.460000   0.020000   3.480000 (  3.475513)
like image 973
Chris Avatar asked Nov 25 '12 18:11

Chris


People also ask

How do I check if an array contains all elements?

1) Check if an array contains a string If you want to ingore the letter cases when checking, you can: First, return a new array that contains all elements in lowercase using the map() and toLocaleLowerCase() methods. Then, use the includes() method to check.

How do you check if an array has squared elements of another array?

Try sorting both arrays and iterating over both of them at the same, first squaring the number from the first array and then checking if it is equal to the element from the second array. Once you reach non-equal elements return false, otherwise return true.

How do you get the elements of one array which are not present in another array using JavaScript?

Use the . filter() method on the first array and check if the elements of first array are not present in the second array, Include those elements in the output.


2 Answers

class Array
  def contains_all? other
    other = other.dup
    each{|e| if i = other.index(e) then other.delete_at(i) end}
    other.empty?
  end
end
like image 147
sawa Avatar answered Oct 16 '22 22:10

sawa


Here's a naive and straightforward implementation (not the most efficient one, likely). Just count the elements and compare both elements and their occurrence counts.

class Array
  def contains_all? ary
    # group the arrays, so that 
    #   [2, 1, 1, 3] becomes {1 => 2, 2 => 1, 3 => 1}
    my_groups = group_and_count self
    their_groups = group_and_count ary

    their_groups.each do |el, cnt|
      if !my_groups[el] || my_groups[el] < cnt
        return false
      end
    end

    true
  end

  private
  def group_and_count ary
    ary.reduce({}) do |memo, el|
      memo[el] ||= 0
      memo[el] += 1
      memo
    end
  end

end

[1, 2, 3].contains_all? [1, 2]   # => true
[1, 2, 3].contains_all? [1, 2, 2] # => false
[2, 1, 2, 3].contains_all? [1, 2, 2] # => true
[1, 2, 3].contains_all? [] # => true
[].contains_all? [1, 2] # => false
like image 37
Sergio Tulentsev Avatar answered Oct 16 '22 20:10

Sergio Tulentsev