一切正常,直到sequentce将唯一的元素传递给此函数。最简单的重现方式是:
var sumOfSquares = Enumerable.Range(5, 1).Aggregate((s, i) => s + i*i);
// sumOfSquares == 5
我认为这个版本的Aggregate应该抛出一个异常,以防序列只包含一个元素。 我是对的还是我错过了一些细节?
答案 0 :(得分:7)
那应该不会失败。根据{{3}}:
源的第一个元素用作初始聚合值。
因此,在这种情况下,您只需返回第一个元素(5)并且不执行聚合。没有错误。
正如Anthony Pegram所指出的那样,documentation可以指定聚合的种子值。将种子设置为0会给出答案25,这可能就是您想要的。
var sumOfSquares = Enumerable.Range(5, 1).Aggregate(0, (s, i) => s + i * i);
当然,你不应该使用Aggregate - 你可以使用Sum。
var sumOfSquares = Enumerable.Range(5, 1).Sum(i => i * i);
我想虽然这只是一个简化的例子。
答案 1 :(得分:4)
还有另一种重载,你可以提供适当的种子并获得我认为你想要的结果。
var sumOfSquares = Enumerable.Range(5, 1).Aggregate(0, (s, i) => s + i * i);
在此代码中,0是初始种子,s
是累计值,i
是当前项。这会产生值25. (5, 2)
产生61,(5, 3)
产生110,等等。
答案 2 :(得分:0)
为什么要这样?取一个数字的总和是完全有效的。
此外,为了让调用者避免异常,他需要做这样的事情:
public double MySum(IEnumerable<double> seq) {
switch (seq.Count()) {
case 0: return 0.0;
case 1: return seq.First();
default: return seq.Aggregate((s, i) => s + i);
}
}
大量的调用,也需要两次(或至少2个第一个元素)传递序列。
答案 3 :(得分:0)
如果你没有提供种子(请参阅Anthony Pegram的答案以获得一个很好的例子),那么Aggregate
函数对只有一个项目的IEnumerable几乎没有任何作用。序列中的第一个元素成为种子,IEnumerable中没有其他项目,它将要做什么?因此,如果未指定种子,Aggregate
函数将返回第一个元素的值。您可以使用以下编译和运行的代码实际看到它:
var c = 0;
var result = Enumerable.Range(5,1).Aggregate((acc,x) => acc + (x / c));
//result == 5
将其更改为Enumerable.Range(5,2)
并立即抛出'除以零'错误。
参考:{备注'部分中的msdn