How can I check whether one array is a subset of another array, regardless of the order of elements?
a1 = [3, 6, 4]
a2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
...?
a1 is a subset of a2
Easiest may be:
(a1 - a2).empty?
set
is stdlib, so it's arguable to say that it is less pure that using list differences.
Commented
Jun 13, 2016 at 14:29
Use sets. Then you can use set.subset?
. Example:
require 'set'
a1 = Set[3,6,4]
a2 = Set[1,2,3,4,5,6,7,8,9]
puts a1.subset?(a2)
Output:
true
See it working online: ideone
proper_subset?
if you didn't want identical sets to return true.
Commented
May 13, 2012 at 0:36
The data structure you already have is perfect, just check the intersection:
(a1 & a2) == a1
Update: The comment discussing permutations is interesting and creative, but quite incorrect as the Ruby implementors anticipated this concern and specified that the order of the result is the order of a1
. So this does work, and will continue to work in the future. (Arrays are ordered data structures, not sets. You can't just permute the order of an array operation.)
I do rather like Dave Newton's answer for coolness, but this answer also works, and like Dave's, is also core Ruby.
a1 & a2
will give a permutation of a1, which if the elements are not in the same order, will give false when comparing it ==
to a1. For example, a1=%w(a c); a2= %w(a b c); perm=a1&a2; (may give ['c','a']); perm==a1 => false
. What is guaranteed to work is a1.permutation.include?(a1&a2)
.
&
method on Array.
It's therefore also not necessary to sort the result.
Commented
May 16, 2016 at 21:09
Perhaps not fast, but quite readable
def subset?(a,b)
a.all? {|x| b.include? x}
end
x.in? b
also works with ActiveSupport. (stackoverflow.com/a/10601055/4960855)
a1 = [1, 1]
anda2 = [1,2,3,4,5,6,7,8,9]
?