Tabla de contenidos:
Aggregate
El operador Aggregate va acumulando los elementos de una secuencia aplicando una función.
- Código necesario para los ejemplos
- Aggregate estándar
- Aggregate + valor de inicio
- Aggregate + valor de inicio + funcion elemento resultante
Código necesario para los ejemplos:
Una lista de números:
List<int> numeros = new List<int> {5, 2, 20, 5, 4, 4};
Aggregate estándar:
public static TSource Aggregate<TSource>( this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func )
Este operador es bien complicado de entender al principio, voy a poner el ejemplo y explicarlo con el:
int suma = numeros.Aggregate((an, pos) => an + pos);
Como veis, el operador toma como parámetro un delegado el cual recibe 2 valores y devuelve otro.
El primer elemento que recibe es el resultado de dicho delegado en la iteración anterior y el segundo es el siguiente elemento.
En la primera iteración al no haber ningun resultado todavía, el primer valor es el primer elemento y el segundo valor es el segundo elemento.
Como esto es difícil de asimilar, vamos a hacer una especie de “debugging”:
Primera iteración:
an -> 5
pos -> 2
Segunda iteración:
an -> 7
pos -> 20
Tercera iteración:
an -> 27
pos -> 5
Y así hasta terminar con todos los elementos.
Como se puede ver, empieza tomando los 2 primeros valores, los suma (que es lo que hace nuestro delegado) y devuelve la suma. Esa suma será el primer valor del delegado y el segundo será un nuevo elemento de la secuencia. Los volverá a sumar y así hasta que termina. En otras palabras, va acumulando los resultados hasta llegar al final.
El resultado final es:
40
Aggregate + valor de inicio:
public static TAccumulate Aggregate<TSource, TAccumulate>( this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func )
Esta sobrecarga recibe un valor de inicio. Como ya sabes, el operador Aggregate va iterando por cada elemento y acumulando los resultados. Al principio no tiene nada acumulado, pero con esta sobrecarga podemos especificar un valor de inicio.
Por ejemplo, queremos a volver a sumar los números, pero ahora en vez de empezar con el acumulador a 0, lo iniciamos a 20:
int suma = numeros.Aggregate(20, (an, pos) => an + pos);
Entonces en la primera iteración sería:
an -> 20
pos -> 5
Entonces el resultado sería:
60
Aggregate + valor de inicio + funcion elemento resultante:
public static TResult Aggregate<TSource, TAccumulate, TResult>( this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector )
Además del valor de inicio, ahora tenemos la posibilidad de aplicarle una función al resultado final, o sea, al valor acumulado que hemos conseguido al terminar todas las iteraciones.
Por ejemplo, vamos a volver a sumar los números, empezaremos por 20 y cuando terminemos lo vamos a dividir por 2:
int suma = numeros.Aggregate(20, (an, pos) => an + pos, res => res / 2);
¿Ya no nos cuesta entenderlo verdad?
Empezamos a sumar con el contador a 20, y terminamos con el valor 60. Ese valor lo dividimos entre 2 asi que el resultado es:
30
Volver a la tabla de contenidos
Average
Con el operador Average podemos calcular la media de una secuencia de valores numéricos.
Código necesario para los ejemplos:
Una lista de números enteros:
List<int> numeros = new List<int> {5, 2, 20, 5, 4, 4};
Una lista de números en coma flotante con un valor nulo:
List<double?> numeros2 = new List<double?> {null, 42, 5.4, 3.2, 2, 4 };
Average estándar:
public static TResult Average<TResult>( this IEnumerable<TResult> source )
El operador Average tiene múltiples sobrecargas, pero todas hacen lo mismo solo que cada una trabaja con un tipo distinto.
La lista de tipos con la que trabaja average es:
- Decimal
- Decimal?
- Double
- Double?
- Int32
- Int32?
- Int64
- Int64?
- Single
- Single?
¿Cual es la media de la primera secuencia de números?:
double media = numeros.Average();
El resultado es:
6,67
¿Y cual es la media de la segunda secuencia de números que además tiene un valor nulo?:
double? media = numeros2.Average();
11,32
Average + función de transformación:
En esta sobrecarga podemos aplicar una función de transformación a cada elemento antes de hacer la media.
Vamos a multiplicar por dos cada número de la secuencia de enteros y hacer la media luego:
double media = numeros.Average(n => n*2);
El resultado es:
13,33
Volver a la tabla de contenidos
Count
El operador Count cuenta el número de elementos de una secuencia.
Código necesario para los ejemplos:
Una lista de nombres:
List<string> nombres = new List<string> { "Jesus", "Maria", "Julia", "Alvaro", "Manolo" };
Count estándar:
public static int Count<TSource>( this IEnumerable<TSource> source )
Usamos Count en una secuencia en la que queremos contar sus elementos. Devuelve un int con el número de elementos de dicha secuencia.
Por ejemplo, ¿Cuántos nombres tenemos?
int count = nombres.Count();
La respuesta es:
5
Count + condición:
public static int Count<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate )
Si lo que realmente queremos es contar la cantidad de elementos de una secuencia que cumplen cierta condición, podemos ahora usar un delegado que usaremos como dicha condición.
¿Cuántos nombres terminan en o?
int count = nombres.Count(n => n.EndsWith("o"));
La respuesta es:
2
Volver a la tabla de contenidos
LongCount
El operador LongCount cuenta el número de elementos de una secuencia. A diferencia de Count, LongCount devuelve un long y no un int.
Código necesario para los ejemplos:
Una lista de nombres:
List<string> nombres = new List<string> { "Jesus", "Maria", "Julia", "Alvaro", "Manolo" };
LongCount estándar:
public static long LongCount<TSource>( this IEnumerable<TSource> source )
Usamos LongCount en una secuencia en la que queremos contar sus elementos. Devuelve un long con el número de elementos de dicha secuencia.
Por ejemplo, ¿Cuántos nombres tenemos?
long count = nombres.LongCount();
La respuesta es:
5
LongCount + condición:
public static long LongCount<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate )
Si lo que realmente queremos es contar la cantidad de elementos de una secuencia que cumplen cierta condición, podemos ahora usar un delegado que usaremos como dicha condición.
¿Cuántos nombres empiezan por J?
long count = nombres.LongCount(n => n.StartsWith("J"));
La respuesta es:
2
Volver a la tabla de contenidos
Max
El operador Max devuelve el valor máximo de una secuencia de valores.
Código necesario para los ejemplos:
Una lista de números enteros:
List<int> numeros = new List<int> {5, 2, 20, 5, 4, 4};
Max estándar:
public static TSource Max<TSource>( this IEnumerable<TSource> source )
El operador Max tiene múltiples sobrecargas, pero todas hacen lo mismo solo que cada una trabaja con un tipo distinto.
La lista de tipos con la que trabaja Max es:
- Decimal
- Decimal?
- Double
- Double?
- Int32
- Int32?
- Int64
- Int64?
- Single
- Single?
¿Cual es el valor máximo de nuestra lista de números?:
int maximo = numeros.Max();
Usamos la sobrecarga correspondiente para el tipo de datos correspondiente de la secuencia.
El resultado es:
20
Max + función de transformación:
public static TResult Max<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, TResult> selector )
͉sta sobrecarga aplicará una función a cada elemento antes de buscar el valor máximo de la secuencia.
Vamos a calcular el cuadrado de cada número y luego ver el mayor:
int maximo = numeros.Max(n => n*n);
El resultado es:
400
Volver a la tabla de contenidos
Min
El operador Min devuelve el valor mínimo de una secuencia de valores.
Código necesario para los ejemplos:
Una lista de números enteros:
List<int> numeros = new List<int> {5, 2, 20, 5, 4, 4};
Min estándar:
public static TSource Min<TSource>( this IEnumerable<TSource> source )
El operador Mix tiene múltiples sobrecargas, pero todas hacen lo mismo solo que cada una trabaja con un tipo distinto.
La lista de tipos con la que trabaja Min es:
- Decimal
- Decimal?
- Double
- Double?
- Int32
- Int32?
- Int64
- Int64?
- Single
- Single?
¿Cual es el valor mínimo de nuestra lista de números?:
int minimo = numeros.Min();
Usamos la sobrecarga correspondiente para el tipo de datos correspondiente de la secuencia.
El resultado es:
2
Min + función de transformación:
public static TResult Min<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, TResult> selector )
͉sta sobrecarga aplicará una función a cada elemento antes de buscar el valor mínimo de la secuencia.
Vamos a multiplicar cada número por cinco y calcular el mínimo:
int minimo = numeros.Min(n => n * 5);
El resultado es:
10
Volver a la tabla de contenidos
Sum
El operador Sum devuelve la suma de los valores de una secuencia.
Código necesario para los ejemplos:
Una lista de números enteros:
List<int> numeros = new List<int> {5, 2, 20, 5, 4, 4};
Sum estándar:
El operador Sum tiene múltiples sobrecargas, pero todas hacen lo mismo solo que cada una trabaja con un tipo distinto.
La lista de tipos con la que trabaja Sum es:
- Decimal
- Decimal?
- Double
- Double?
- Int32
- Int32?
- Int64
- Int64?
- Single
- Single?
¿Cual es la suma de los números de la secuencia?
int suma = numeros.Sum();
¿Recuerdas que hicimos esto mismo usando Average? Obviamente esta es la forma correcta de hacer este tipo de operación.
El resultado es:
40
Sum + función de transformación:
͉sta sobrecarga aplicará una función a cada elemento antes de buscar el valor mínimo de la secuencia.
Vamos a restarle tres a cada número y luego hacer la suma:
int suma = numeros.Sum(n => n - 3);
El resultado es:
22
Volver a la tabla de contenidos
Tags: LINQ


Muy buenos estos post amigos ayudan mucho,pero tengo una consulta a ver si me puedes ayudar, si tengo un datatable mas o menos con esta estructura.
Cliente Documento Subtotal Descuento Total
a Factura 2 1 1
b Factura 3 2 1
c Nota Venta 4 2 2
c Nota Venta 5 1 4
a Nota Venta 6 1 5
a Liquidacion 7 2 5
b Liquidacion 8 2 6
Y deseo obtener en otro datatable para enviar a un reporte un resumen del primero agrupar por documento y saber cuantos regostros hay y los totales, algo como esto
Documento NoReg Total
Factura 2 2
Nota Venta 3 11
Liquidacion 2 11
Podria usar linq para obtener esto y como seria?
Espero que me pueda ayudar
Me alaga que me preguntes, pero este no es el mejor sitio para hacer preguntas.
Te puedo decir que si miras el GroupBy te podrá ayudar, pero necesitarás usar varios operadores.
Quierosaber como contar una serie de elemntos distintivamente