C# Linq按最快日期获取第一行订单,其中B列不是;“过期”;或;“已取消”;
我有一份清单C# Linq按最快日期获取第一行订单,其中B列不是;“过期”;或;“已取消”;,c#,linq,C#,Linq,我有一份清单 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
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
我只想在最快的日期前订购一行,但状态为“正在进行”或“过期”,在上面我想要这个
467 2015-02-21 00:00:00.000 Overdue
我不知道怎么做但我试过了
var fruits = fruits.order(p => p.time);
var // not sure whats next
将OrderBy()
与First()
一起使用:
将OrderBy()
与First()
一起使用:
您可以使用
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();
您可以使用
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();
出于好奇,我想说: 如果您正在对对象执行LINQ操作(因此您的
fruits
不是db),那么执行OrderBy
是一个O(nlogn)
操作,在这种情况下是无用的。。。使用(稍作更改,因为MinBy()
不支持空枚举):
及
公共静态类EnumerableTools
{
公共静态TSource MinByOrDefault(此IEnumerable源,Func选择器)
{
IComparer comparer=comparer.Default;
使用(var sourceIterator=source.GetEnumerator())
{
如果(!sourceIterator.MoveNext())
{
//空源
返回默认值(TSource);
}
var min=sourceIterator.Current;
var minKey=选择器(最小值);
while(sourceIterator.MoveNext())
{
var current=sourceIterator.current;
var currentKey=选择器(当前);
if(比较器比较(currentKey,minKey)<0)
{
最小值=电流;
minKey=currentKey;
}
}
返回最小值;
}
}
}
这保证在时间上是
O(n)
,在空间上是O(1)
(不需要排序,也不分配额外的空间)只是出于好奇,我要提到:
如果您正在对对象执行LINQ操作(因此您的fruits
不是db),那么执行OrderBy
是一个O(nlogn)
操作,在这种情况下是无用的。。。使用(稍作更改,因为MinBy()
不支持空枚举):
及
公共静态类EnumerableTools
{
公共静态TSource MinByOrDefault(此IEnumerable源,Func选择器)
{
IComparer comparer=comparer.Default;
使用(var sourceIterator=source.GetEnumerator())
{
如果(!sourceIterator.MoveNext())
{
//空源
返回默认值(TSource);
}
var min=sourceIterator.Current;
var minKey=选择器(最小值);
while(sourceIterator.MoveNext())
{
var current=sourceIterator.current;
var currentKey=选择器(当前);
if(比较器比较(currentKey,minKey)<0)
{
最小值=电流;
minKey=currentKey;
}
}
返回最小值;
}
}
}
这保证在时间上是
O(n)
,在空间上是O(1)
(不需要排序,也不分配额外的空间)所以你想要按时间顺序进行或过期的水果?旁注:如果第467项的日期为2015
,或2018
,则创建一个枚举可能会更有意义?是什么?你可能想考虑使用<代码> EnUM <代码> >你的代码>状态< /代码>属性……所以你想要的是正在进行的或过期的按时间排序的水果?旁注:如果第467项的日期为2015
,或2018
,则创建一个枚举可能会更有意义?您可能想考虑使用<代码> EnUM <代码> >代码>状态> <代码>属性…@ XANATOS,这是一个有效的点,我也思考了<代码> FrestRealSuth。然而,OP根本没有提到Linq到实体或数据库(仅“表”)。此外,有时您确实希望在找不到任何东西的情况下抛出异常。@xanatos,这是一个有效的观点,我也考虑了FirstOrDefault
。然而,OP根本没有提到Linq到实体或数据库(仅“表”)。此外,有时您确实希望在找不到任何异常的情况下抛出异常。
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;
}
}
}