George Swan
Вот определение метода расширения.
public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func);
Как говорит Грифф в своем решении, это эквивалентно a
for
петля. Это может сбить с толку, первый параметр-это семя, он не ссылается на первый элемент в массиве, это дополнительное значение. Таким образом, если бы это было 2 вместо 1, результат был бы 560. Я предпочитаю называть параметры аналогично тем, которые даны в определении, и использовать "элемент" для элемента перечисляемого.
int[] numbers = { 1, 4, 7, 10 };
int product = numbers.Aggregate(seed:2,(accumulator, item) => accumulator * item);
Console.WriteLine(product); // output: 560
На самом деле вам не нужно устанавливать начальное значение в вашем примере. Существует перегрузка метода, который использует первое значение перечисляемого в качестве начального значения.
int[] numbers = { 1, 4, 7, 10 };
int product = numbers.Aggregate((accumulator, item) => accumulator * item);
Интересный момент о семени заключается в том, что оно может быть разным.
Type
к перечисляемому
Type
но это одно и то же
Type
это возвращается из метода. Существует еще одна перегрузка метода, которая позволяет использовать результат агрегации в качестве параметра функции. Так что вы можете сделать что-то вроде этого. Определение семени как
double
и вернуть а
double
из функции.
var intCollection = new int[] { 1,2,3,4 };
double squareRoot10 = intCollection.Aggregate(0.00D,
(accumulator, item) => accumulator += item,
accumulator=> Math.Sqrt(accumulator));
Более практичным примером может быть создание собственного аккумулятора
Type
с помощью методов обработки "предметов" и возврата результата накопления.