2009-04-16 29 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 一直用可以排序依据()如果要确认没有重复后加上鲜明的()。