我有一个这样的对象列表
MyObject
.StartDate
.EndDate
.Number
我需要知道数字总和高于某个数字的最后一天是什么时候。只有在 StartDate 和 EndDate 之间的数字才会输入当天的总和。
var list = List<MyObject>();
from list
where (list.Sum(x => x.Number) > 100)
select lastdate
LINQ可以做到这一点吗?
假设列表是有序的:
var list = List<MyObject>();
var lastDate = list.First(item => list.Where(l => l.EndDate <= item.EndDate)
.Sum(x => x.Number) > 100
)
.EndDate
如果不只是添加订单:
var list = List<MyObject>();
var lastDate = list.OrderBy(item => item.EndDate)
.First(item => list.Where(l => l.EndDate <= item.EndDate)
.Sum(x => x.Number) > 100
)
.EndDate
但是,您正在重新扫描每个项目的循环。使用简单的循环会更有效:
DateTime endDate;
int total;
foreach(var item in list.OrderBy(item => item.EndDate))
{
total += item.Number;
if(total > 100)
{
endDate = item.EndDate;
break;
}
}
var result = items.Where(t => items.SkipWhile(tt => tt.EndDate != t.EndDate)
.Sum(tt => tt.Number) > 100).First().EndDate;
您可能需要其他属性来执行此操作。不确定如何在单行 LINQ 语句中执行此操作:
public class MyObjectWithSum
{
public DateTime StartDate {get;set;}
public DateTime EndDate {get;set;}
public int Number {get;set;}
public int SumAsOfEndDate {get;set;}
}
var list = new List<MyObjectWithSum>();
foreach(var item in list)
{
item.SumAsOfEndDate = list.Sum(x => x.Number).Where(y => y.EndDate <= item.EndDate);
}
list.OrderBy(x => x.EndDate).First(x => x.SumAsOfEndDate > 100).EndDate;
var lastdate = list.OrderByDescending(l => l.EndDate)
.First(l =>
list.Where(s => s.StartDate <= l.EndDate && l.EndDate <= s.EndDate)
.Sum(s => s.Number) > 100).EndDate;
我们不需要检查任何日期,因为对 sum 的更改取决于对 enddate 的更改。
所以:
这样可以防止不必要的迭代,并且在您检查的日期之后结束但也开始的项目将被忽略。