Set theory in LINQ
October 16, 2016
set theory
LINQ
.NET
development
A set is a collection that cannot contain duplicates and the order of the elements in a set doesn’t matter. In .NET the datastructure HashSet is meant for this. This means that if you try to declare a set with duplicates the compiler will just ignore them. Every element has a unique hash code to keep track of them:
var a = new HashSet<int>() {1, 2, 2, 3, 4};
a.ToList().ForEach(Console.WriteLine);
output:
1
2
3
4
These two sets are equal:
var a = new HashSet<int>() {1, 2, 3};
var b = new HashSet<int>() {3, 2, 1};
var c = b.SetEquals(a);
Console.WriteLine(c);
output:
True
Before we start to use the benefits of the hashset we might have to convert our data from another type:
var myArray = new int[] {1, 3, 5, 7};
var mySet = new HashSet(myArray);
Union
Union
Math:
A = {1, 3, 5, 7}
B = {1, 2, 4, 6}
C = A ∪ B = {1, 2, 3, 4, 5, 6, 7}
C#:
var a = new HashSet<int>() {1, 3, 5, 7};
var b = new HashSet<int>() {1, 2, 4, 6};
a.UnionWith(b);
a.ToList().ForEach(Console.WriteLine);
output:
1
3
5
7
2
4
6
Intersection
Intersection
Math:
A = {1, 3, 5, 7}
B = {1, 2, 4, 6}
C = A ∩ B = {1}
C#:
var a = new HashSet<int>() {1, 3, 5, 7};
var b = new HashSet<int>() {1, 2, 4, 6};
a.IntersectWith(b);
a.ToList().ForEach(Console.WriteLine);
output:
1
Symmetric difference (The opposite of intersection)
Symmetric difference
Symmetric difference aka Xor is the opposite of intersection.
Math:
A ⊖ B
C#:
var a = new HashSet<int>() {1, 3, 5, 7};
var b = new HashSet<int>() {1, 2, 4, 6};
a.SymmetricExceptWith(b);
a.ToList().ForEach(Console.WriteLine);
output:
3
5
7
2
4
6
Comment: It is possible to obtain this by writing a.Except(b).UnionWith(b.Except(a));
. However it’s not as efficient.
Set difference
Set difference
The complement
Math:
A \ B
C#:
var a = new HashSet<int>() {1, 3, 5, 7};
var b = new HashSet<int>() {1, 2, 4, 6};
var c = a.Except(b);
c.ToList().ForEach(Console.WriteLine);
output:
3
5
7
Cartesian product
Math:
A x B
C#:
var a = new HashSet<string>() { "cat", "dog", "ape", "pig" };
var result = a.SelectMany(p => new HashSet<int>() { 1, 2, 3 }, (p, i) => p + " says " + i);
result.ToList().ForEach(Console.WriteLine);
output:
cat says 1
cat says 2
cat says 3
dog says 1
dog says 2
dog says 3
ape says 1
ape says 2
ape says 3
pig says 1
pig says 2
pig says 3
Collections in LINQ
Merge
Math:
C#:
var a = new int[] {1, 3, 5, 7};
var b = new int[] {1, 2, 4, 6};
var c = a.Concat(b).ToArray();
c.ToList().ForEach(Console.WriteLine);
output:
1
3
5
7
1
2
4
6