Ok, I need to test if two IEnumerable<T>
are equal. The order of the elements is important, which means that:
{1, 2, 4, 1, 3} and {1, 2, 1, 3, 4} should not be equal.
I've seen a few answers on this site explaining how to do this with linq
: for example, here
The problem is that I have to repeatedly test for equality of pretty big collections (thousands of elements) that have a high probability of not being equal, so performance is a factor to bear in mind. The way I see it, all the linq
methods shown in the referred answer (Count
or Except
) need to, if I'm not mistaken, iterate through the whole collection which in the general case is not necessary.
I came up with this code, which works reasonably well (I think) and is fast enough. I was wondering if I'm missing some obvious built in way of doing this (I don't want to reinvent the wheel here if possible.)
public static bool IsEqualTo<T>(this IEnumerable<T> inner, IEnumerable<T> other) where T: IEquatable<T>
{
if (inner == null)
throw new ArgumentNullException();
if (object.ReferenceEquals(inner, other))
return true;
if (object.ReferenceEquals(other, null))
return false;
using (var innerEnumerator = inner.GetEnumerator())
using (var otherEnumerator = other.GetEnumerator())
{
while (innerEnumerator.MoveNext())
{
if (!otherEnumerator.MoveNext() || !innerEnumerator.Current.Equals(otherEnumerator.Current))
return false;
}
return !otherEnumerator.MoveNext();
}
}
Basically you are looking to short-circuit the evaluation when an element isn't found.
IEnumerable.SequenceEqual
(MSDN) already does this; proved out by the implementation in: http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs (line 806)
When order is important, you should be able to write a simple while loop:
int i = 0;
int aCount = a.Count(); //Use `IList` so you can use the property for efficiency
int bCount = b.Count(); //Use `IList` so you can use the property for efficiency
if (aCount != bCount)
return false;
while (a.ElementAt(i) == b.ElementAt(i))
i++;
return i == aCount;
Your function does basically the same thing, and would work fine.
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