Finding symmetric difference with LINQ
Use HashSet<T>
directly - it has a SymmetricExceptWith
method:
HashSet<T> data = new HashSet<T>(a);
data.SymmetricExceptWith(b);
EDIT: If you want to maintain the order, here's an alternative:
HashSet<T> data = new HashSet<T>(a);
data.IntersectWith(b);
foreach (T t in a.Concat(b))
{
if (!data.Contains(t))
{
yield return t;
}
}
This has the following important differences:
- Both
a
andb
are iterated over twice. In some cases that could be a very bad thing - you could callToList
on each of them to start with to retain a buffer. If there are duplicates in either
a
orb
, they will be yielded multiple times. If you wanted to avoid this you could keep a set of already-yielded values. At this point, it would be equivalent to:a.Concat(b).Except(a.Intersect(b))
That's still only two set operations instead of the three in your original code though.
Given a.Except(b) and b.Except(a) are disjoint, you can use concat
instead of union
, saving a set operator (and concat
is more efficient).
return a.Except (b).Concat (b.Except (a));
This still runs through each list twice.