This method iterates once over both arrays.
For each array, it creates a hash with the number of occurences of each element.
It then checks that for every unique element in subset, there are at least as many elements in superset.
class Array
def count_by
each_with_object(Hash.new(0)) { |e, h| h[e] += 1 }
end
def subset_of?(superset)
superset_counts = superset.count_by
count_by.all? { |k, count| superset_counts[k] >= count }
end
end
[1, 2, 3, 3, "abc", "de", "f"].count_by
#=> {1=>1, 2=>1, 3=>2, "abc"=>1, "de"=>1, "f"=>1}
[1, 2, 3, 3].count_by
#=> {1=>1, 2=>1, 3=>2}
[1, 2, 3, 3].subset_of? [1, 2, 3, 3, "abc", "de", "f"]
#=> true
[2, 2, "abc"].subset_of? [1, 2, 3, 3, "abc", "de", "f"]
#=> false
If you don't want to patch the Array class, you could define :
count_by(array) and subset_of?(array1, array2).