Enumerable.Aggregate error - PullRequest
       1

Enumerable.Aggregate error

3 голосов
/ 16 декабря 2010

Все работало нормально, пока последовательность с единственным элементом не была передана этой функции. Самый простой способ воспроизвести это:

var sumOfSquares = Enumerable.Range(5, 1).Aggregate((s, i) => s + i*i);
// sumOfSquares == 5

Я думаю, что эта версия Aggregate должна выдавать исключение в случае, когда последовательность содержит только один элемент. Я прав или есть некоторые детали, которые я пропустил?

Ответы [ 4 ]

7 голосов
/ 16 декабря 2010

Это не должно провалиться.Согласно документации :

Первый элемент источника используется в качестве начального совокупного значения.

Так что в этом случае вы просто получаетепервый элемент back (5) и агрегации не выполняются.Нет ошибки.

Как указал Энтони Пеграм, существует другая перегрузка , где вы можете указать начальное значение для агрегации.Если задать начальное значение 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);

Я думаю, что это был просто упрощенный пример.

4 голосов
/ 16 декабря 2010

Есть еще одна перегрузка, когда вы можете предоставить подходящее семя и получить то, что я считаю желаемым результатом.

var sumOfSquares = Enumerable.Range(5, 1).Aggregate(0, (s, i) => s + i * i);

В этом коде 0 - начальное начальное число, s - накопленное значение, i - текущая позиция. Это дает значение 25. (5, 2) производит 61, (5, 3) производит 110 и т. Д.

0 голосов
/ 16 декабря 2010

Если вы не предоставите начальное число (отличный пример см. В ответе Энтони Пеграма), то функция 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 в разделе «Замечания»

0 голосов
/ 16 декабря 2010

С чего бы это? Вполне допустимо взять сумму одного числа.

Кроме того, чтобы вызывающий абонент избежал исключения, ему необходимо сделать что-то вроде этого:

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 первых элемента).

...