Agrupando Listas en Memoria en C# con LINQ y Expresiones Lambda
Al trabajar con listas en C#, puede que te encuentres con diversos escenarios donde necesites agrupar elementos basándote en una propiedad específica. Por ejemplo, supongamos que tienes una colección de objetos Foo
, y deseas organizarlos según los valores de sus propiedades Bar
. Aquí es donde entra en juego el poder de LINQ (Language Integrated Query) y las expresiones lambda. En esta publicación del blog, exploraremos cómo agrupar listas en memoria usando estas características de C# de manera efectiva.
Entendiendo el Problema
Imagina que tienes una lista de objetos Foo
, donde cada Foo
tiene propiedades Bar
y Lum
. Algunas instancias de Foo
pueden compartir el mismo valor para Bar
. Tu objetivo es agrupar estas instancias de Foo
por sus valores de Bar
y luego iterar sobre las colecciones agrupadas para acceder a sus correspondientes valores de Lum
. Esto puede mejorar la organización de datos y facilitar la manipulación de conjuntos de datos específicos.
Ejemplo de Escenario
Consideremos un ejemplo específico con la siguiente lista de instancias de Foo
:
var foos = new List<Foo> {
new Foo{Bar = 1,Lum = 1},
new Foo{Bar = 1,Lum = 2},
new Foo{Bar = 2,Lum = 3},
};
Resultado Deseado
Queremos agrupar estas instancias de Foo
por sus valores de Bar
, produciendo algo como:
- Para
Bar = 1
:Lum = 1
,Lum = 2
- Para
Bar = 2
:Lum = 3
Solución Usando LINQ
Puedes agrupar los objetos Foo
utilizando la cláusula group by
de LINQ. Aquí te mostramos cómo se puede lograr:
var groupedFoos = from foo in foos
group foo by foo.Bar into grouped
let lums = from g in grouped
select g.Lum
select new { Bar = grouped.Key, Lums = lums };
Pasos Explicados
- Group By: La parte
group foo by foo.Bar
agrupa las instancias deFoo
basándose en la propiedadBar
. - Into Grouped: Esto crea un nuevo ámbito para cada grupo.
- Seleccionando Valores de Lum: La declaración
let lums
te permite crear una nueva colección que consiste en valores deLum
de los objetos agrupados. - Selección Final: La selección final ensambla todo en un nuevo objeto que contiene el valor de
Bar
y su correspondiente lista de valores deLum
.
Solución Usando Expresiones Lambda
Alternativamente, puedes lograr el mismo resultado usando expresiones lambda, que pueden ofrecer una sintaxis más concisa. Aquí te mostramos cómo:
var groupedFoos = foos.GroupBy(x => x.Bar)
.Select(y => new { Bar = y.Key, Lums = y.Select(z => z.Lum) });
Cómo Funciona
- GroupBy: Este método toma una función lambda para especificar la propiedad por la cual queremos agrupar, a saber
x.Bar
. - Select: Después de agrupar, utilizamos
Select
para crear un nuevo objeto anónimo para cada grupo, que contiene los valores deBar
y los correspondientes valores deLum
.
Iterando a Través de Datos Agrupados
Independientemente de si utilizas LINQ o expresiones lambda, iterar a través de los datos agrupados permanece igual. Puedes recorrer cada grupo y imprimir los valores de Lum
de la siguiente manera:
foreach (var group in groupedFoos)
{
Console.WriteLine("Lums para Bar#" + group.Bar);
foreach (var lum in group.Lums)
{
Console.WriteLine(lum);
}
}
La Salida será:
Lums para Bar#1
1
2
Lums para Bar#2
3
Conclusión
Agrupar listas en memoria utilizando LINQ o expresiones lambda en C# es una forma poderosa de organizar tus datos. Ya sea que prefieras la legibilidad de la sintaxis de LINQ o la concisión de las expresiones lambda, ambos enfoques te permitirán lograr la agrupación deseada de tus datos de manera efectiva.
Para aquellos que buscan profundizar su comprensión de LINQ, considera explorar 101 Muestras de LINQ para más ejemplos comprensivos.
Si tienes alguna pregunta o quisieras compartir tus experiencias sobre la agrupación de datos en C#, ¡no dudes en dejar un comentario abajo!