我有这个表达:
group i by i.ItemId into g
select new
{
Id = g.Key,
Score = g.Sum(i => i.Score)
}).ToDictionary(o => o.Id, o => o.Score);
而不是g.Sum
我想使用Aggregate
来获取数学产品。
为了确保它与.Sum
(但作为产品)的工作方式相同,我尝试制作一个只返回总和的聚合函数...
Score = g.Aggregate(0.0, (sum, nextItem) => sum + nextItem.Score.Value)
但是,这与使用.Sum
的结果不同。任何idas为什么?
nextItem.Score
的类型为double?
。
答案 0 :(得分:3)
public static class MyExtensions
{
public static double Product(this IEnumerable<double?> enumerable)
{
return enumerable
.Aggregate(1.0, (accumulator, current) => accumulator * current.Value);
}
}
答案 1 :(得分:1)
事实是,在你的例子中,你开始乘以0.0 - 乘以零得到零,最后结果将为零。
正确的是使用乘法的identity属性。虽然向数字加零会使数字保持不变,但相同的属性适用于乘以1。因此,启动产品聚合的正确方法是以数字1.0开始乘法。
答案 2 :(得分:0)
如果您不确定汇总查询中的初始值,并且您实际上并不需要(例如此示例),我建议您根本不要使用它。
您可以使用不会取初始值的聚合重载 - http://msdn.microsoft.com/en-us/library/bb549218.aspx
喜欢这个
int product = sequence.Aggregate((x, acc) => x * acc);
评估为item1 * (item2 * (item3 * ... * itemN))
。
而不是
int product = sequence.Aggregate(1.0, (x, acc) => x * acc);
评估为1.0 * (item1 * (item2 * (item3 * ... * itemN)))
。
//编辑: 但是有一个重要的区别。当输入序列为空时,前者会抛出InvalidOperationException。后者1返回种子值,因此为1.0。