If you can populate a one column table with the values that you need to test against then you could do this. If the count is equal to the number of values you're testing against then the array forms a subset. Of course this assumes that you're using a SQL variant with intersect. Dems' solution should work everywhere.
Simple Approach: A simple approach is to run two nested loops and generate all subarrays of the array A[] and use one more loop to check if any of the subarray of A[] is equal to the array B[]. Efficient Approach : An efficient approach is to use two pointers to traverse both the array simultaneously.
Simple: use array subtraction. On array subtraction, you will know whether or not one array is a subset of the other. You can use array_intersect also. array_diff(['a', 'b', 'c'], ['a', 'b']) will return ['c'].
bool isSubset = !t2.Except(t1).Any();
Use HashSet instead of List if working with sets. Then you can simply use IsSubsetOf()
HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};
bool isSubset = t2.IsSubsetOf(t1);
Sorry that it doesn't use LINQ. :-(
If you need to use lists, then @Jared's solution works with the caveat that you will need to remove any repeated elements that exist.
This is a significantly more efficient solution than the others posted here, especially the top solution:
bool isSubset = t2.All(elem => t1.Contains(elem));
If you can find a single element in t2 that isn't in t1, then you know that t2 is not a subset of t1. The advantage of this method is that it is done all in-place, without allocating additional space, unlike the solutions using .Except or .Intersect. Furthermore, this solution is able to break as soon as it finds a single element that violates the subset condition, while the others continue searching. Below is the optimal long form of the solution, which is only marginally faster in my tests than the above shorthand solution.
bool isSubset = true;
foreach (var element in t2) {
if (!t1.Contains(element)) {
isSubset = false;
break;
}
}
I did some rudimentary performance analysis of all the solutions, and the results are drastic. These two solutions are about 100x faster than the .Except() and .Intersect() solutions, and use no additional memory.
If you are unit-testing you can also utilize the CollectionAssert.IsSubsetOf method :
CollectionAssert.IsSubsetOf(subset, superset);
In the above case this would mean:
CollectionAssert.IsSubsetOf(t2, t1);
@Cameron's solution as an extension method:
public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
return !a.Except(b).Any();
}
Usage:
bool isSubset = t2.IsSubsetOf(t1);
(This is similar, but not quite the same as the one posted on @Michael's blog)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With