Checking Collections Have The Same Elements
[C#]
There may be occasions when you have two collections and want to verify that they are the same.
int[] first = [1, 2, 3, 4, 5];
int[] second = [5, 2, 3, 4, 1];
int[] third = [1, 2, 3, 4, 5];
int[] fourth = first;
The first order of business is to decide what “they are the same” means.
- Do they contain the same elements?
- Do they contain the same elements and in the same order?
- Do they refer to the same
object
?
Depending on your definition, you must approach this problem differently.
We can start with what seems like a valid approach - an equality check.
Console.WriteLine(first == second);
Console.WriteLine(first == third);
Console.WriteLine(first == fourth);
This will print the following:
False
False
True
The third one is true
because fourth
is merely a reference to first. This is also why the other two comparisons return false
.
If you want to compare the elements and their order, you use the Linq SeqenceEqual method.
Console.WriteLine(first.SequenceEqual(second));
Console.WriteLine(first.SequenceEqual(third));
Console.WriteLine(first.SequenceEqual(fourth));
This returns the following:
False
True
True
Which makes sense.
The challenge is to verify that two collections contain the same elements, regardless of order. In our example first
([1, 2, 3, 4, 5]
) and second
([5, 2, 3, 4, 1]
).
There are a number of ways to do this.
Order, Then Compare
Here, we explicitly order the elements first and then compare them.
Console.WriteLine(first.Order().SequenceEqual(second.Order()));
Use Specialized Data Structures
We can also make use of the fact that there is a specialized data structure, a HashSet, that stores a collection of unique elements.
So we put both collections into different sets and check that the sets have the same elements using the SetEquals method.
Console.WriteLine(new HashSet<int>(first).SetEquals(new HashSet<int>(second)));
You can simplify this still further by making use of Linq
extension methods that directly convert a collection to a HashSet
, ToHashSet
Console.WriteLine(first.ToHashSet().SetEquals(second.ToHashSet()));
FluentAssertions
If you are conducting these comparisons in the context of unit testing, an even better approach is to use the FluentAssertions library, which has extension methods for this sort of problem.
If we want to verify that two collections have the same elements and in the same order, we do it like this:
// Check have the same elements, in the same order
first.Should().Equal(second);
first.Should().Equal(third);
This will throw an exception for the first comparison, with this message
Expected collection to be equal to {5, 2, 3, 4, 1}, but {1, 2, 3, 4, 5} differs at index 0.
If we want to check that two collections have the same elements, regardless of order, we do it like this:
// Check have the same elements, regardless of order
first.Should().BeEquivalentTo(second);
first.Should().BeEquivalentTo(third);
The examples in this post use the Array
but will also work for most collections that implement IEnumberable - such as Lists.
Happy hacking!