Skip to content Skip to sidebar Skip to footer

How To Check If A List Is Ordered?

I am doing some unit tests and I want to know if there's any way to test if a list is ordered by a property of the objects it contains. Right now I am doing it this way but I don't

Solution 1:

If you are using MSTest, you may want to take a look at CollectionAssert.AreEqual.

Enumerable.SequenceEqual may be another useful API to use in an assertion.

In both cases you should prepare a list that holds the expected list in the expected order, and then compare that list to the result.

Here's an example:

var studyFeeds = Feeds.GetStudyFeeds(2120, DateTime.Today.AddDays(-200), 20);   
var expectedList = studyFeeds.OrderByDescending(x => x.Date);
Assert.IsTrue(expectedList.SequenceEqual(studyFeeds));

Solution 2:

A .NET 4.0 way would be to use the Enumerable.Zip method to zip the list with itself offset by one, which pairs each item with the subsequent item in the list. You can then check that the condition holds true for each pair, e.g.

var ordered = studyFeeds.Zip(studyFeeds.Skip(1), (a, b) =>new { a, b })
                        .All(p => p.a.Date < p.b.Date);

If you're on an earlier version of the framework you can write your own Zip method without too much trouble, something like the following (argument validation and disposal of the enumerators if applicable is left to the reader):

publicstaticIEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> selector)
{
    var e1 = first.GetEnumerator();
    var e2 = second.GetEnumerator();
    while (e1.MoveNext() & e2.MoveNext()) // one & is importantyieldreturnselector(e1.Current, e2.Current);
}

Solution 3:

Nunit 2.5 introduced CollectionOrderedContraint and a nice syntax for verifying the order of a collection:

Assert.That(collection, Is.Ordered.By("PropertyName"));

No need to manually order and compare.

Solution 4:

If your unit testing framework has helper methods to assert equality of collections, you should be able do something like this (NUnit flavored):

var sorted = studyFeeds.OrderBy(s => s.Date);
CollectionAssert.AreEqual(sorted.ToList(), studyFeeds.ToList());

The assert method works with any IEnumerable, but when both collections are of type IList or "array of something", the error message thrown when the assert fails will contain the index of the first out-of-place element.

Solution 5:

The solutions posted involving sorting the list are expensive - determining if a list IS sorted can be done in O(N). Here's an extension method which will check:

publicstaticboolIsOrdered<T>(this IList<T> list, IComparer<T> comparer = null)
{
    if (comparer == null)
    {
        comparer = Comparer<T>.Default;
    }

    if (list.Count > 1)
    {
        for (int i = 1; i < list.Count; i++)
        {
            if (comparer.Compare(list[i - 1], list[i]) > 0)
            {
                returnfalse;
            }
        }
    }
    returntrue;
}

A corresponding IsOrderedDescending could be implemented easily by changing > 0 to < 0.

Post a Comment for "How To Check If A List Is Ordered?"