Esto puede sonar cojo, pero no he podido encontrar una explicación realmente buena Aggregate
.
Bueno significa breve, descriptivo, integral con un ejemplo pequeño y claro.
La definición más fácil de entender Aggregate
es que realiza una operación en cada elemento de la lista teniendo en cuenta las operaciones anteriores. Es decir, realiza la acción en el primer y segundo elemento y lleva el resultado hacia adelante. Luego opera sobre el resultado anterior y el tercer elemento y continúa. etc.
Ejemplo 1. Sumar números
var nums = new[]{1,2,3,4};
var sum = nums.Aggregate( (a,b) => a + b);
Console.WriteLine(sum); // output: 10 (1+2+3+4)
Esto agrega 1
y 2
hacer 3
. Luego agrega 3
(resultado del anterior) y 3
(siguiente elemento en secuencia) para hacer 6
. Luego agrega 6
y 4
para hacer 10
.
Ejemplo 2. crear un csv a partir de una matriz de cadenas
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d
Esto funciona de la misma manera. Concatenar a
una coma y b
hacer a,b
. Luego concatena a,b
con una coma y c
hacer a,b,c
. y así.
Ejemplo 3. Multiplicar números usando una semilla
Para completar, hay una sobrecarga de la Aggregate
cual toma un valor semilla.
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)
Al igual que los ejemplos anteriores, esto comienza con un valor de 5
y lo multiplica por el primer elemento de la secuencia 10
dando un resultado de 50
. Este resultado se lleva adelante y se multiplica por el siguiente número en la secuencia 20
para dar un resultado 1000
. Esto continúa a través de los 2 elementos restantes de la secuencia.
Ejemplos en vivo: http://rextester.com/ZXZ64749
Documentos: http://msdn.microsoft.com/en-us/library/bb548651.aspx
Apéndice
El ejemplo 2 anterior usa la concatenación de cadenas para crear una lista de valores separados por una coma. Esta es una forma simplista de explicar el uso de Aggregate
cuál fue la intención de esta respuesta. Sin embargo, si usa esta técnica para crear una gran cantidad de datos separados por comas, sería más apropiado usar a StringBuilder
, y esto es totalmente compatible con el Aggregate
uso de la sobrecarga sembrada para iniciar el 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);
Ejemplo actualizado: http://rextester.com/YZCVXV6464
[1,2,3,4]
será[3,3,4]
entonces[6,4]
y por fin[10]
. Pero en lugar de devolver una matriz de un solo valor, solo obtiene el valor en sí.TakeWhile
entonces unAggregate
- eso es lo mejor de Enumerable extensiones - son fácilmente encadenables. Entonces terminas conTakeWhile(a => a == 'a').Aggregate(....)
. Vea este ejemplo: rextester.com/WPRA60543var csv = string.Join(",", chars)
(sin necesidad de agregados o constructores de cadenas), pero sí, sé que el punto de la respuesta era dar un ejemplo de uso de agregado, por lo que es genial. Pero aún quería mencionar que no se recomienda solo para unir cadenas, ya hay un método dedicado para eso ...var biggestAccount = Accounts.Aggregate((a1, a2) => a1.Amount >= a2.Amount ? a1 : a2);
Depende en parte de la sobrecarga de la que esté hablando, pero la idea básica es:
(currentValue, sequenceValue)
en(nextValue)
currentValue = nextValue
currentValue
Puede encontrar útil la
Aggregate
publicación en mi serie Edulinq : incluye una descripción más detallada (incluidas las diversas sobrecargas) y las implementaciones.Un ejemplo simple es usar
Aggregate
como alternativa aCount
:O quizás sumando todas las longitudes de cadenas en una secuencia de cadenas:
Personalmente, rara vez me parece
Aggregate
útil: los métodos de agregación "a medida" suelen ser lo suficientemente buenos para mí.fuente
El agregado súper corto funciona como un pliegue en Haskell / ML / F #.
Un poco más largos .Max (), .Min (), .Sum (), .Average () todos iteran sobre los elementos en una secuencia y los agregan usando la función de agregado respectiva. .Aggregate () es un agregador generalizado en el sentido de que permite al desarrollador especificar el estado de inicio (también conocido como semilla) y la función de agregado.
Sé que pediste una breve explicación, pero pensé que mientras otros daban un par de respuestas cortas, pensé que tal vez te interesaría una más larga.
Versión larga con código Una forma de ilustrar qué puede hacer es mostrar cómo implementa la Desviación estándar de muestra una vez que usa foreach y una vez que usa .Aggregate. Nota: No he priorizado el rendimiento aquí, así que repito varias veces innecesariamente la recopilación.
Primero, una función auxiliar utilizada para crear una suma de distancias cuadráticas:
Luego, muestra la desviación estándar usando ForEach:
Luego, una vez que use .Agregar:
Tenga en cuenta que estas funciones son idénticas, excepto cómo se calcula sumOfQuadraticDistance:
Versus:
Entonces, lo que hace .Aggregate es que encapsula este patrón de agregación y espero que la implementación de .Aggregate se vea más o menos así:
El uso de las funciones de desviación estándar se vería así:
En mi humilde opinión
Entonces, ¿Agregado ayuda a la legibilidad? En general, me encanta LINQ porque creo que .Where, .Select, .OrderBy, etc., ayuda enormemente a la legibilidad (si evita las .selects jerárquicas en línea). Agregado tiene que estar en Linq por razones de integridad, pero personalmente no estoy tan convencido de que. Agregado agrega legibilidad en comparación con un foreach bien escrito.
fuente
SampleStandardDeviation_Aggregate()
ySampleStandardDeviation_ForEach()
no pueden serprivate
(por defecto en ausencia de un calificador de acceso), por lo que debería haber sido acumulados por cualquierapublic
ointernal
, me pareceUna imagen vale mas que mil palabras
Enumerable.Aggregate tiene tres sobrecargas:
Sobrecarga 1:
Ejemplo:
Esta sobrecarga es simple, pero tiene las siguientes limitaciones:
contrario la función arrojará un
InvalidOperationException
.Sobrecarga 2:
Ejemplo:
Esta sobrecarga es más general:
bIn
).en este caso, la función generará el valor de semilla como resultado.
Sobrecarga 3:
La tercera sobrecarga no es muy útil IMO.
Lo mismo se puede escribir de manera más sucinta mediante el uso de sobrecarga 2 seguido de una función que transforma su resultado.
fuente
Aggegate
en .net que toma unFunc<T, T, T>
.seed
, aplica la función de acumulador N -1 veces; mientras que las otras sobrecargas (que no toman unaseed
) aplicar la función de acumulador de N veces.El agregado se usa básicamente para agrupar o resumir datos.
De acuerdo con MSDN "La función de agregado aplica una función de acumulador sobre una secuencia".
Ejemplo 1: Agregar todos los números en una matriz.
* importante: el valor agregado inicial por defecto es el elemento 1 en la secuencia de la colección. es decir: el valor inicial de la variable total será 1 por defecto.
explicación variable
total: mantendrá el valor de suma (valor agregado) devuelto por la función.
nextValue: es el siguiente valor en la secuencia de la matriz. Este valor se agrega al valor agregado, es decir, total.
Ejemplo 2: Agregar todos los elementos en una matriz. Establezca también el valor inicial del acumulador para comenzar a agregar desde 10.
explicación de argumentos:
El primer argumento es el inicial (valor inicial, es decir, valor inicial) que se utilizará para iniciar la adición con el siguiente valor en la matriz.
El segundo argumento es una función que es una función que requiere 2 int.
1.total: esto se mantendrá igual que antes del valor de suma (valor agregado) devuelto por el func después del cálculo.
2.nextValue:: es el siguiente valor en la secuencia de la matriz. Este valor se agrega al valor agregado, es decir, total.
Además, la depuración de este código le dará una mejor comprensión de cómo funciona el agregado.
fuente
Aprendí mucho de la respuesta de Jamiec .
Si la única necesidad es generar una cadena CSV, puede intentarlo.
Aquí hay una prueba con 1 millón de cadenas
El código fuente está aquí.
fuente
Además de todas las excelentes respuestas aquí, también lo he usado para guiar un artículo a través de una serie de pasos de transformación.
Si una transformación se implementa como a
Func<T,T>
, puede agregar varias transformaciones a ayList<Func<T,T>>
usarAggregate
para recorrer una instancia deT
cada paso.Un ejemplo mas concreto
Desea tomar un
string
valor y recorrerlo a través de una serie de transformaciones de texto que podrían construirse mediante programación.Esto creará una cadena de transformaciones: eliminar espacios iniciales y finales -> eliminar el primer carácter -> eliminar el último carácter -> convertir a mayúsculas. Los pasos en esta cadena se pueden agregar, eliminar o reordenar según sea necesario, para crear cualquier tipo de tubería de transformación que se requiera.
El resultado final de esta tubería específica, es que se
" cat "
convierte"A"
.Esto puede volverse muy poderoso una vez que te das cuenta de que
T
puede ser cualquier cosa . Esto podría usarse para transformaciones de imágenes, como filtros, usandoBitMap
como ejemplo;fuente
El método agregado es un método de extensión para colecciones genéricas. El método agregado aplica una función a cada elemento de una colección. No solo aplica una función, sino que toma su resultado como valor inicial para la próxima iteración. Por lo tanto, como resultado, obtendremos un valor calculado (min, max, avg u otro valor estadístico) de una colección.
Por lo tanto, el método Agregado es una forma de implementación segura de una función recursiva.
Seguro , porque la recursión iterará sobre cada elemento de una colección y no podemos obtener ninguna suspensión de bucle infinito por una condición de salida incorrecta. Recursivo , porque el resultado de la función actual se usa como parámetro para la próxima llamada a la función.
Cómo funciona:
que está haciendo lo mismo que esta función:
fuente
Esta es una explicación sobre el uso
Aggregate
en una API Fluent como Linq Sorting.y veamos que queremos implementar una función de clasificación que tome un conjunto de campos, esto es muy fácil de usar en
Aggregate
lugar de un ciclo for, como este:Y podemos usarlo así:
fuente
Todos han dado su explicación. Mi explicación es así.
El método agregado aplica una función a cada elemento de una colección. Por ejemplo, tengamos la colección {6, 2, 8, 3} y la función Agregar (operador +) que hace (((6 + 2) +8) +3) y devuelve 19
En este ejemplo, se pasa el método con nombre Add en lugar de la expresión lambda.
fuente
Una definición breve y esencial podría ser esta: el método de extensión Agregado de Linq permite declarar una especie de función recursiva aplicada a los elementos de una lista, cuyos operandos son dos: los elementos en el orden en que están presentes en la lista, un elemento a la vez, y el resultado de la iteración recursiva anterior o nada, si no es que aún, recursividad.
De esta forma, puede calcular el factorial de los números o concatenar cadenas.
fuente
Agregado utilizado para sumar columnas en una matriz entera multidimensional
Seleccionar con índice se utiliza dentro de la función Agregado para sumar las columnas coincidentes y devolver una nueva matriz; {3 + 2 = 5, 1 + 4 = 5, 7 + 16 = 23, 8 + 5 = 13}.
Pero contar el número de verdades en una matriz booleana es más difícil ya que el tipo acumulado (int) difiere del tipo fuente (bool); aquí es necesaria una semilla para usar la segunda sobrecarga.
fuente