tags:

views:

233

answers:

2

I want to write a lambda expression to verify that a list is ordered correctly. I have a List where a person has a Name property eg:

IList<Person> people = new List<Person>();
people.Add(new Person(){ Name = "Alan"});
people.Add(new Person(){ Name = "Bob"});
people.Add(new Person(){ Name = "Chris"});

I'm trying to test that the list is ordered ASC by the Name property.So I'm after something like

Assert.That(people.All(....), "list of person not ordered correctly");

How can I write a lambda to check that each Person in the list has a name less that the next person in the list?

+4  A: 

I don't believe there is any LINQ operator which currently covers this case. However you could write an IsOrdered method which does the work. For example.

public static bool IsOrdered<T>(this IEnumerable<T> enumerable) {
  var comparer = Comparer<T>.Default;
  using ( var e = enumerable.GetEnumerator() ) {
    if ( !e.MoveNext() ) {
      return true;
    }
    var previous = e.Current;
    while (e.MoveNext()) {
      if ( comparer.Compare(previous, e.Current) > 0) {
        return false;
      }
      previous = e.Current;
    }
    return true;
  }
}

Then you could use the following to verify your list:

var isOrdered = people.Select(x => x.Name).IsOrdered();
JaredPar
I've added a post on my blog regarding this question for anyone thats interested. http://www.dav-evans.com/?p=67
Dav Evans
+5  A: 

Here's an alternative to Jared's solution - it's pretty much the same, but using a foreach loop and a Boolean variable to check whether or not this is the first iteration. I usually find that easier than iterating manually:

public static bool IsOrdered<T>(this IEnumerable<T> source)
{
  var comparer = Comparer<T>.Default;
  T previous = default(T);
  bool first = true;

  foreach (T element in source)
  {
      if (!first && comparer.Compare(previous, element) > 0)
      {
          return false;
      }
      first = false;
      previous = element;
  }
  return true;
}
Jon Skeet