2009-04-16 4 views
2

Je veux écrire une expression lambda pour vérifier qu'une liste est ordonnée correctement. J'ai une liste dans laquelle une personne a une propriété de nom par exemple:L'expression lambda pour vérifier la liste est correctement ordonnée

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

Je suis en train de vérifier que la liste est ordonnée ASC par le nom property.So Je suis après quelque chose comme

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

Comment puis-je écrire un lambda pour vérifier que chaque personne de la liste a un nom moins que la personne suivante dans la liste?

+6

Un indice rapide - si vous utilisez un constructeur sans paramètre dans un initialiseur d'objet, vous n'avez pas besoin de l'option(). Par exemple: people.Add (new Person {Name = "Alan"}); –

Répondre

5

est ici une alternative à la solution de Jared - il est à peu près la même chose, mais en utilisant une boucle foreach et une variable booléenne pour vérifier si ou pas c'est la première itération. Je trouve généralement que plus facile que itérer manuellement:

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; 
} 
4

Je ne crois pas qu'il existe un opérateur LINQ qui couvre actuellement ce cas. Cependant, vous pouvez écrire une méthode IsOrdered qui fait le travail. Par exemple.

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; 
    } 
} 

Ensuite, vous pouvez utiliser les éléments suivants pour vérifier votre liste:

var isOrdered = people.Select(x => x.Name).IsOrdered(); 
0

Je sais que c'est une vieille question, mais j'ai une solution très agréable pour cette LINQ:

people.Zip(people.OrderBy(p => p.Name), (a, b) => a == b).All(eq => eq); 

Fondamentalement, vous fusionnez une séquence avec la séquence ordonnée, et la projection d'une valeur booléenne indiquant si les deux entrées sont égales:

"Alan" -- "Alan" => true 
"Bob" -- "Bob" => true 
"Chris" -- "Chris" => true 

Puis, avec la méthode All vous demander si tous les éléments dans la collection sont true.

0

Qu'en est-:

people.SequenceEqual(people.OrderBy(x=>x.Name)); 

SequenceEqual() est disponible depuis 3,5 Vous pouvez ajouter Distinct() après OrderBy() si vous voulez confirmer qu'il n'y a pas de doublons.

Questions connexes