我想写一个lambda表达式来验证列表是否正确排序。我有一个List,其中一个人有一个Name属性,例如:
IList<Person> people = new List<Person>();
people.Add(new Person(){ Name = "Alan"});
people.Add(new Person(){ Name = "Bob"});
people.Add(new Person(){ Name = "Chris"});
我正在尝试通过Name属性测试列表是否按顺序排列ASC。所以我在做了像
这样的事情Assert.That(people.All(....), "list of person not ordered correctly");
如何编写lambda来检查列表中的每个人的名字是否少于列表中的下一个人?
答案 0 :(得分: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;
}
答案 1 :(得分: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();
答案 2 :(得分:0)
我知道这是一个老问题,但我使用Linq有一个非常好的解决方案:
people.Zip(people.OrderBy(p => p.Name), (a, b) => a == b).All(eq => eq);
基本上,您正在将序列与有序序列合并,并投射一个bool值,指示两个条目是否相等:
"Alan" -- "Alan" => true
"Bob" -- "Bob" => true
"Chris" -- "Chris" => true
然后使用All
方法询问集合中的所有项目是否为true
。
答案 3 :(得分:0)
怎么样:
people.SequenceEqual( people.OrderBy( x=>x.Name ) );
自3.5以来,SequenceEqual()已经可用 如果要确认没有重复项,可以在OrderBy()之后添加Distinct()。