我有一个清单,
public Class Fruit
{
public int id;
public string status;
public DateTime time;
public .... other columns
}
我有一张这样的表,
458 2015-03-19 00:00:00.000 Completed
469 2015-03-23 00:00:00.000 Inprogress
467 2015-02-21 00:00:00.000 Overdue
470 2015-05-25 00:00:00.000 Completed
我只希望按最快的日期订购1行,但状态为" Inprogress"或者"过期",在上面我想要这个,
467 2015-02-21 00:00:00.000 Overdue
我不确定我是怎么做的,
var fruits = fruits.order(p => p.time);
var // not sure whats next
答案 0 :(得分:3)
将OrderBy()
与First()
:
var result = fruits.Where(x => x.status == "Inprogress" || x.status == "Overdue")
.OrderBy(x => x.time)
.First();
答案 1 :(得分:3)
您可以使用FirstOrDefault()
选择符合特定条件的第一个项目,如果没有此类项目,则使用null
。
var firstNotExpired = fruits.OrderBy(f => f.time)
.FirstOrDefault(f => !(f.status == "Expired" ||
f.status == "Cancelled"));
这很简洁,但效率低,因为它需要对整个列表进行排序。这更有效:
var firstNotExpired = fruits.Where(f => !(f.status == "Expired" ||
f.status == "Cancelled"))
.OrderBy(f => f.time)
.FirstOrDefault();
答案 2 :(得分:0)
出于好奇,我提到https://stackoverflow.com/a/6680893/613130:
如果您正在执行LINQ到对象(因此您的fruits
不是数据库),执行OrderBy
是O(nlogn)
操作,在这种情况下是无用的...使用https://code.google.com/p/morelinq/(稍加一些更改,因为MinBy()
不支持空的枚举):
var firstNotExpired = fruits.Where(f => !(f.status == "Expired" || f.status == "Cancelled"))
.MinByOrDefault(f => f.time);
和
public static class EnumerableTools
{
public static TSource MinByOrDefault<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
IComparer<TKey> comparer = Comparer<TKey>.Default;
using (var sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
// Empty source
return default(TSource);
}
var min = sourceIterator.Current;
var minKey = selector(min);
while (sourceIterator.MoveNext())
{
var current = sourceIterator.Current;
var currentKey = selector(current);
if (comparer.Compare(currentKey, minKey) < 0)
{
min = current;
minKey = currentKey;
}
}
return min;
}
}
}
保证时间为O(n)
,空间为O(1)
(不需要排序,也不分配额外空间)