Loved SLaks version. Just for completeness, you can use HashSet
method IsSubsetOf when performing set operations (also check IsSupersetOf
method). There are pros and cons for this approach. Next code shows an example:
var list1 = new HashSet<string>{ "Dog", "Cat", "Bird" };
var list2 = new HashSet<string>{ "Dog", "Cat" };
if (list2.IsSubsetOf(list1))
{
Console.Write("All items in list2 are in list1");
}
Except
method is streaming in nature. In query list2.Except(list1)
list1
is buffered completely into memory, and you iterate one item at a time through list2
. IsSubsetOf
works eagerly in the opposite manner. This starts to make a difference when you have huge sets of data.
To analyse the worst case performance, here is some code from Except
implementation at Monos Enumerable (dotPeek gives very similar results, just less readable)
var items = new HashSet<TSource> (second, comparer); //list1.Count
foreach (var element in first) //list2.Count
if (items.Add (element)) //constant time
yield return element;
as result O(list1.Count + list2.Count)
, loops aren't nested.
IsSubset
has next method call, if second IEnumerable
is HashSet
(decompiled via dotPeek):
private bool IsSubsetOfHashSetWithSameEC(HashSet<T> other)
{
foreach (T obj in this) //list2.Count
if (!other.Contains(obj)) //constant time
return false;
return true;
}
Resulting in O(list2.Count)
if list1
is a HashSet
.