Это может звучать глупо, но я не смог найти действительно хорошего объяснения Aggregate
.
Хороший означает короткий, описательный, всеобъемлющий с небольшим и ясным примером.
Самым простым для понимания определением Aggregate
является то, что он выполняет операцию с каждым элементом списка с учетом операций, которые были выполнены ранее. То есть он выполняет действие над первым и вторым элементом и переносит результат вперед. Затем он воздействует на предыдущий результат и третий элемент и переносит вперед. и т.п.
Пример 1. Суммирование чисел
var nums = new[]{1,2,3,4};
var sum = nums.Aggregate( (a,b) => a + b);
Console.WriteLine(sum); // output: 10 (1+2+3+4)
Это добавляет 1
и 2
сделать 3
. Затем добавляет 3
(результат предыдущего) и 3
(следующий элемент в последовательности), чтобы сделать 6
. Затем добавляет 6
и 4
сделать 10
.
Пример 2. Создание CSV из массива строк
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d
Это работает во многом таким же образом. Объединить a
запятую и b
сделать a,b
. Затем соединяет a,b
запятую и c
делает a,b,c
. и так далее.
Пример 3. Умножение чисел с использованием начального числа
Для полноты, существует перегрузка из Aggregate
которого принимает начальное значение.
var multipliers = new []{10,20,30,40};
var multiplied = multipliers.Aggregate(5, (a,b) => a * b);
Console.WriteLine(multiplied); //Output 1200000 ((((5*10)*20)*30)*40)
Как и в приведенных выше примерах, это начинается со значения 5
и умножает его на первый элемент последовательности, 10
дающий результат 50
. Этот результат переносится вперед и умножается на следующее число в последовательности, 20
чтобы получить результат 1000
. Это продолжается через оставшиеся 2 элемента последовательности.
Живые примеры: http://rextester.com/ZXZ64749
Документы: http://msdn.microsoft.com/en-us/library/bb548651.aspx
добавление
В приведенном выше примере 2 используется конкатенация строк для создания списка значений, разделенных запятой. Это упрощенный способ объяснить использование Aggregate
которого было целью этого ответа. Однако, если использовать эту технику для создания большого количества данных, разделенных запятыми, было бы более целесообразно использовать a StringBuilder
, и это полностью совместимо с Aggregate
использованием сеяной перегрузки для инициирования StringBuilder
.
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate(new StringBuilder(), (a,b) => {
if(a.Length>0)
a.Append(",");
a.Append(b);
return a;
});
Console.WriteLine(csv);
Обновленный пример: http://rextester.com/YZCVXV6464
[1,2,3,4]
будет[3,3,4]
потом[6,4]
и наконец[10]
. Но вместо того, чтобы возвращать массив одного значения, вы просто получаете само значение.TakeWhile
тогдаAggregate
- то будет beatuty расширений перечислимого - они легко цепные. Итак, вы в конечном итогеTakeWhile(a => a == 'a').Aggregate(....)
. Посмотрите этот пример: rextester.com/WPRA60543var csv = string.Join(",", chars)
(без необходимости в агрегате или строителях строк) - но да, я знаю, смысл ответа был в том, чтобы привести пример использования агрегата, так что это круто. Но я все же хотел упомянуть, что это не рекомендуется для простого объединения строк, для этого уже есть метод, выделенный для этого ...var biggestAccount = Accounts.Aggregate((a1, a2) => a1.Amount >= a2.Amount ? a1 : a2);
Отчасти это зависит от того, о какой перегрузке вы говорите, но основная идея такова:
(currentValue, sequenceValue)
в(nextValue)
currentValue = nextValue
currentValue
Вы можете найти
Aggregate
пост в моей серии Edulinq полезным - он включает в себя более подробное описание (включая различные перегрузки) и реализации.Один простой пример использует
Aggregate
в качестве альтернативыCount
:Или, возможно, суммирование всех длин строк в последовательности строк:
Лично я редко бываю
Aggregate
полезным - «адаптированные» методы агрегации обычно достаточно хороши для меня.источник
Супер короткий Агрегат работает как фолд в Haskell / ML / F #.
Немного длиннее .Max (), .Min (), .Sum (), .Average () все перебирает элементы в последовательности и агрегирует их, используя соответствующую функцию агрегирования. .Aggregate () является обобщенным агрегатором в том смысле, что он позволяет разработчику указать начальное состояние (также называемое семенем) и функцию агрегирования.
Я знаю, что вы попросили короткого объяснения, но я решил, что другие дали пару коротких ответов, и я подумал, что вас, возможно, заинтересует чуть более длинный.
Длинная версия с кодом Один из способов проиллюстрировать, что это может быть, - показать, как вы реализуете стандартное отклонение образца, однажды используя foreach, а затем - .Aggregate. Примечание: у меня нет приоритета производительности, поэтому я несколько раз повторяю всю коллекцию без необходимости
Сначала вспомогательная функция используется для создания суммы квадратичных расстояний:
Затем выберите стандартное отклонение, используя ForEach:
Затем один раз с помощью .Aggregate:
Обратите внимание, что эти функции идентичны за исключением того, как рассчитывается sumOfQuadraticDistance:
Против:
Так что .Aggregate делает то, что он инкапсулирует этот шаблон агрегатора, и я ожидаю, что реализация .Aggregate будет выглядеть примерно так:
Использование функций стандартного отклонения будет выглядеть примерно так:
ИМХО
Так .Aggregate помогает читабельности? В общем, я люблю LINQ, потому что я думаю, что .Where, .Select, .OrderBy и т. Д. Очень помогают удобочитаемости (если вы избегаете встроенных иерархических .Selects). Агрегат должен быть в Linq по причинам полноты, но лично я не настолько убежден, что .Agregate добавляет удобочитаемость по сравнению с хорошо написанным foreach.
источник
SampleStandardDeviation_Aggregate()
иSampleStandardDeviation_ForEach()
не может бытьprivate
(по умолчанию при отсутствии квалификатора доступа), поэтому должен был быть накоплен либо,public
либоinternal
, как мне кажетсяОдна картинка стоит тысячи слов
Enumerable.Aggregate имеет три перегрузки:
Перегрузка 1:
Пример:
Эта перегрузка проста, но имеет следующие ограничения:
противном случае функция сгенерирует
InvalidOperationException
.Перегрузка 2:
Пример:
Эта перегрузка носит более общий характер:
bIn
).в этом случае функция выдаст начальное значение как результат.
Перегрузка 3:
Третья перегрузка не очень полезна ИМО.
То же самое можно записать более кратко, используя перегрузку 2, за которой следует функция, которая преобразует свой результат.
источник
Aggegate
в .net нет перегрузки, которая принимаетFunc<T, T, T>
.seed
, применяет функцию аккумулятора N -1 раз; в то время как другие перегрузки (что делать потратьтеseed
) применить агрегатную функцию N раз.Агрегат в основном используется для группировки или суммирования данных.
Согласно MSDN «Агрегатная функция применяет функцию накопителя к последовательности».
Пример 1: Добавить все числа в массив.
* важно: начальное совокупное значение по умолчанию - 1 элемент в последовательности сбора. т.е.: общее начальное значение переменной будет 1 по умолчанию.
объяснение переменной
total: он будет содержать итоговое значение (агрегированное значение), возвращаемое функцией.
nextValue: это следующее значение в последовательности массива. Это значение затем добавляется к агрегированному значению, т.е.
Пример 2: Добавить все элементы в массив. Также установите начальное значение аккумулятора, чтобы начать добавлять с 10.
Аргументация объяснения:
первый аргумент - это начальный (начальное значение, т.е. начальное значение), который будет использоваться для начала сложения со следующим значением в массиве.
Второй аргумент - это func, который принимает 2 int.
1.total: он будет таким же, как и до суммирования (агрегированного значения), возвращаемого функцией после вычисления.
2.nextValue :: это следующее значение в последовательности массивов. Это значение затем добавляется к агрегированному значению, т.е.
Также отладка этого кода даст вам лучшее понимание того, как работает агрегат.
источник
Много узнал из ответа Джеймица .
Если вам нужно только создать строку CSV, вы можете попробовать это.
Вот тест с 1 миллионом строк
Исходный код здесь
источник
В дополнение ко всем отличным ответам здесь, я также использовал это, чтобы пройти элемент через ряд шагов преобразования.
Если преобразование реализовано как a
Func<T,T>
, вы можете добавить несколько преобразований в aList<Func<T,T>>
и использовать егоAggregate
для прохождения экземпляраT
через каждый шаг.Более конкретный пример
Вы хотите взять
string
значение и пройти через серию текстовых преобразований, которые могут быть построены программно.Это создаст цепочку преобразований: Удалить начальные и конечные пробелы -> удалить первый символ -> удалить последний символ -> преобразовать в верхний регистр. Шаги в этой цепочке могут быть добавлены, удалены или переупорядочены по мере необходимости, чтобы создать любой тип конвейера преобразования, который требуется.
Конечным результатом этого конкретного конвейера является то, что
" cat "
делается"A"
.Это может стать очень мощным, когда вы поймете, что это
T
может быть что угодно . Это можно использовать для преобразования изображений, например фильтров, используяBitMap
в качестве примера;источник
Агрегатный метод - это метод расширения для универсальных коллекций. Метод агрегирования применяет функцию к каждому элементу коллекции. Не только применяет функцию, но и принимает ее результат в качестве начального значения для следующей итерации. Таким образом, в результате мы получим вычисленное значение (min, max, avg или другое статистическое значение) из коллекции.
Следовательно, метод Aggregate является формой безопасной реализации рекурсивной функции.
Безопасно , потому что рекурсия будет повторяться для каждого элемента коллекции, и мы не можем получить приостановку бесконечного цикла из-за неправильного условия выхода. Рекурсивно , потому что результат текущей функции используется в качестве параметра для следующего вызова функции.
Как это работает:
который делает то же самое, что и эта функция:
источник
Это объяснение использования
Aggregate
в Fluent API, таком как Linq Sorting.и давайте посмотрим, что мы хотим реализовать функцию сортировки, которая принимает набор полей, это очень легко использовать
Aggregate
вместо цикла for, например так:И мы можем использовать это так:
источник
Каждый дал свое объяснение. Мое объяснение таково.
Метод агрегирования применяет функцию к каждому элементу коллекции. Например, у нас есть коллекция {6, 2, 8, 3} и функция Add (operator +), которую она выполняет (((6 + 2) +8) +3) и возвращает 19
В этом примере вместо лямбда-выражения передается именованный метод Add.
источник
Краткое и существенное определение может быть следующим: метод расширения Linq Aggregate позволяет объявить своего рода рекурсивную функцию, применяемую к элементам списка, операндов которых два: элементы в том порядке, в котором они присутствуют в списке, один элемент за раз, и результат предыдущей рекурсивной итерации или ничего, если еще не рекурсия.
Таким образом, вы можете вычислить факториал чисел или объединить строки.
источник
Агрегат, используемый для суммирования столбцов в многомерном целочисленном массиве
Select with index используется в функции Aggregate для суммирования совпадающих столбцов и возврата нового массива; {3 + 2 = 5, 1 + 4 = 5, 7 + 16 = 23, 8 + 5 = 13}.
Но подсчет числа истин в логическом массиве более сложен, так как накопленный тип (int) отличается от типа источника (bool); здесь семя необходимо для того, чтобы использовать вторую перегрузку.
источник