假设我有以下
var list = new []{
new { Price = 1000, IsFirst = true},
new { Price = 1100, IsFirst = false},
new { Price = 450, IsFirst = true},
new { Price = 300, IsFirst = false}
};
我希望生成以下输出:
Price IsFirst First Second Final
----------------------------------
1000 True 1000 0 1000
1100 False 0 1100 -100
450 True 450 0 350
300 False 0 300 50
是否有可能将某种聚合函数处理到当前行?我喜欢在纯LINQ中拥有所有东西,但截至目前我除了手动迭代列表并有条件地对列进行求和之外别无选择。
var result = list.Select(x => new
{
Price = x.Price,
IsFirst = x.IsFirst,
First = x.IsFirst ? x.Price : 0,
Second = !x.IsFirst ? x.Price : 0,
Final = 0 // ???
}).ToList();
int sum = 0;
for(int i=0; i<result.Count(); i++)
{
sum += (result[i].IsFirst ? result[i].Price : - result[i].Price);
// updating Final value manually
}
答案 0 :(得分:3)
最简单的方法是使用Microsoft Reactive Extension Team&#34; Interactive Extension&#34;方法Scan
。 (使用NuGet并查找Ix-Main
。)
var query =
list
.Scan(new
{
Price = 0,
IsFirst = true,
First = 0,
Second = 0,
Final = 0
}, (a, x) => new
{
Price = x.Price,
IsFirst = x.IsFirst,
First = x.IsFirst ? x.Price : 0,
Second = !x.IsFirst ? x.Price : 0,
Final = a.Final + (x.IsFirst ? x.Price : - x.Price)
});
这给出了:
但是,您可以使用内置的Aggregate
运算符执行此操作:
var query =
list
.Aggregate(new []
{
new
{
Price = 0,
IsFirst = true,
First = 0,
Second = 0,
Final = 0
}
}.ToList(), (a, x) =>
{
a.Add(new
{
Price = x.Price,
IsFirst = x.IsFirst,
First = x.IsFirst ? x.Price : 0,
Second = !x.IsFirst ? x.Price : 0,
Final = a.Last().Final + (x.IsFirst ? x.Price : - x.Price)
});
return a;
})
.Skip(1);
你得到的结果相同。
答案 1 :(得分:2)
您想要的是总计。
据我所知,在LINQ中没有内置的方法可以做到这一点,但是各种各样的人都有编写扩展方法来做到这一点。我很快在网上找到的就是这个:
基于此,将代码转换为
的扩展方法应该相当容易IsFirst = true
,答案 2 :(得分:0)
您可以这样做:
int final = 0;
var result = list.Select(x => new
{
Price = x.Price,
IsFirst = x.IsFirst,
First = x.IsFirst ? x.Price : 0,
Second = !x.IsFirst ? x.Price : 0,
Final = x.IsFirst ? final+=x.Price : final-=x.Price
}).ToList();
但是你需要在linq表达式之外定义一个整数(final)来跟踪总和。