2009-04-16 47 views
2

我想寫一個lambda表達式來驗證列表中正確排序。我有一個列表,其中一人有一個Name屬性如:lambda表達式驗證列表中正確排序

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

我試圖測試該列表由名稱property.So有序ASC像

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

我如何寫一個lambda檢查列表中的每個人都有一個名字小於旁邊的人在列表中?

+6

一個快速提示 - 如果您在對象初始值設定項中使用無參數構造函數,則不需要()。例如:people.Add(new Person {Name =「Alan」}); – 2009-04-16 16:51:29

回答

5

下面是Jared的解決方案的替代方案 - 這幾乎是相同的,但使用foreach循環和布爾變量來檢查是否或者不是這是第一次迭代。我通常會發現比手動迭代簡單:

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

我不相信這是目前涵蓋這種情況下任何LINQ運營商。然而,你可以寫一個IsOrdered方法來完成這項工作。例如。

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

然後,你可以使用以下方法來驗證您的列表:

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

我知道這是一個老問題,但我對這個使用LINQ一個非常好的解決方案:

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

基本上,你合併一個序列與有序序列,並突出表明這兩個項目是否相等一個布爾值:

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

然後用All方法,你問,如果所有項目在收集是true

0

什麼:

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

SequenceEqual()自3.5 一直用可以排序依據()如果要確認沒有重複後加上鮮明的()。