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
comments powered by Disqus