Out of curiosity: What comparer is used when sorting a bunch of objects using the following extension method?
OrderBy(x=> x)
Background: I have to check wether two ISet< T > instances contain the same elements and considered to use the
bool setsEqual = MySet.SequenceEqual(OtherSet);
method. As the order of those elements contained in the sets are not defined and may differ, a SequenceEqual would fail in those cases where the internal order is not the same. So i would have to explictly define an order. As the order algo for itself is completely irrelevant as long as it´s stable, i just used an "Identity" lambda expression:
bool setsEqual = MySet.OrderBy(x => x).SequenceEqual(OtherSet.OrderBy(x => x);
But what does "Compare the objects themselves" mean to the code? As this OrderBy extension method is a generic one, there must be a default compare algo in place that is able to sort objects without knowing anything more about it, and that would mean a comparison for sorting had to be delegated to the type of the set elements itself. Is there an interface that the elements´ type would have to support, or is there a default comparer (may be comparing internal memory addresses of objects) in place?
To answer the question of sorting: sorting uses IComparable<T>
or IComperable
if that isn't implemented. The IComperable
interfaces force you to implement a int CompareTo(object)
method (or int CompareTo(T)
method if you used the typed version).
The order of your elements is determined by the sign of the int. The value returned is interpreted as follows:
0
: the two objects are equivalent (i.e. the same)-1
: the compared object precedes this object (i.e. comes before this object)1
: the compared object follows this object (i.e. comes after this object)The actual value is ignored, the sign is all that matters. If you implement your own IComparable
interface, you have to choose the semantics for sort order.
Many objects already implement IComparable
already, like all your numbers, strings, etc. You'll need to implement it explicitly if you need to sort objects you've created yourself. It's not a bad practice if you intend those objects to be displayed in a list on screen at all.
As to your specific case, where you just need to determine if a set and another IEnumerable
are equivalent, then you would use the ISet<T>.SetEquals(IEnumerable<T>)
method which is implemented in the standard library set implementations. Sets, by definition, only guarantee the values are unique, so as long as the number of elements are the same, you only need to detect that all the elements in one IEnumerable
can be found in the set.
The method used the IComparable<T>
-or the IComparable
-interface depending on which of both are implemented. If none is implemented the order is arbitrary.
However you won´t need to order you instances before comparing the sets. Simply loop one set and check if all of its elements are contained in the other set. Or use this:
var areEqual = firstSet.All(x => secondSet.Contains(x)) && secondSet.All(x => firstSet.Contains(x));
Or even simpler:
var areEqual = !firstSet.Except(secondSet).Any() && !secondSet.Except(firstSet).Any();
Both ways perform much faster than your appraoch as the iteration of elements stops when the first element is found that does not fit. Using OrderBy
you´d loop all elements, regardless if there was already a mismatch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With