Title: Perform set operations on enumerable lists in C#
To demonstrate set operations, this example creates two lists of Person objects. The Person class implements IEquatable.
The code then uses the following code to display the lists and their intersection, union, difference, and exclusive or (xor).
// Display the values.
lstA.DataSource = list_a;
lstB.DataSource = list_b;
lstAUnionB.DataSource = list_a.Union(list_b).ToList();
lstAIntersectB.DataSource = list_a.Intersect(list_b).ToList();
lstAMinusB.DataSource = list_a.Except(list_b).ToList();
lstAXorB.DataSource = list_a.Xor(list_b);
The code first sets the lstA and lstB controls' DataSource properties so they display the original lists. It then uses the LINQ Union, Intersect, and Except methods to get the union, intersection, and exclusion of the lists (A - B). The Except method returns the items in list A except those that are in list B.
Notice that the union and intersection methods do not include duplicates. For example, Art Archer appears in both lists but it appears only once in the union. In fact, Bev Baker appears twice in both lists but it still only appears once in the union.
The final line of code uses the Xor method. For some reason, LINQ doesn't include this operation, so I implemented it in the following extension method.
public static class ListExtensions
{
public static IEnumerable<T> Xor<T>(
this IEnumerable<T> list_a, IEnumerable<T> list_b)
{
IEnumerable<T> intersection = list_a.Intersect(list_b).ToList();
IEnumerable<T> only_a = list_a.Except(intersection).ToList();
IEnumerable<T> only_b = list_b.Except(intersection).ToList();
return only_a.Union(only_b);
}
}
This code finds the intersection of the two lists. It then uses the Except method to make versions of the lists that don't include their intersection. Finally, it combines the two to get the Xor of the original lists.
In other words, the code uses this identity:
A ⊕ B = (A - B) ∪ (B - A)
Download the example to experiment with it and to see additional details.
|