Inicio > Cursos > C# > LINQ Avanzado: GroupBy, Join, Aggregate
C#Colecciones y LINQLección 11 de 20

LINQ Avanzado: GroupBy, Join, Aggregate

LINQ avanzado tiene operaciones equivalentes a SQL: GroupBy agrupa elementos por una propiedad (como GROUP BY en SQL), Join relaciona dos colecciones por una clave común (como JOIN), y Aggregate aplica una función acumuladora de izquierda a derecha (como reduce en JavaScript). La combinación de GroupBy y Select permite crear resúmenes estadísticos complejos en muy pocas líneas.

SelectMany es uno de los métodos más poderosos: aplana colecciones de colecciones. Si tienes List<List<int>>, SelectMany la convierte en una sola List<int>. Es el equivalente de .flat() en JavaScript. C# también ofrece una sintaxis de consulta alternativa con palabras clave (from, where, select, orderby, groupby) que parece más a SQL para quienes prefieren ese estilo. Ambas sintaxis son equivalentes; el compilador las convierte a la misma cosa.

var estudiantes = new List<Estudiante> {
    new("Ana", "Matemáticas", 95),
    new("Bob", "Física", 80),
    new("Carlos", "Matemáticas", 88),
    new("Diana", "Física", 92)
};

record Estudiante(string Nombre, string Materia, int Nota);

// GroupBy - agrupar
var porMateria = estudiantes.GroupBy(e => e.Materia);
foreach (var grupo in porMateria) {
    Console.WriteLine($"{grupo.Key}:");
    foreach (var est in grupo) {
        Console.WriteLine($"  {est.Nombre}: {est.Nota}");
    }
}

// Aggregate (como reduce)
int productorio = new[] {1,2,3,4,5}.Aggregate((acc, x) => acc * x); // 120
string frase = new[] {"Hola", "Mundo", "C#"}.Aggregate((a, b) => $"{a} {b}");

// Join (como SQL JOIN)
var materias = new[] {
    new { Id = 1, Nombre = "Matemáticas" },
    new { Id = 2, Nombre = "Física" }
};

// SelectMany - aplanar listas anidadas
var categorias = new List<List<string>> {
    new() { "a", "b" },
    new() { "c", "d", "e" }
};
var plano = categorias.SelectMany(c => c).ToList();
// { "a", "b", "c", "d", "e" }

// Distinct / Except / Intersect
var lista1 = new[] {1, 2, 3, 4, 5};
var lista2 = new[] {3, 4, 5, 6, 7};
var interseccion = lista1.Intersect(lista2).ToList(); // {3,4,5}
var diferencia = lista1.Except(lista2).ToList();       // {1,2}
var union = lista1.Union(lista2).ToList();             // {1,2,3,4,5,6,7}

// Sintaxis de consulta (estilo SQL)
var consulta = from e in estudiantes
               where e.Nota >= 88
               orderby e.Nota descending
               select new { e.Nombre, e.Nota };
Consejo📊 GroupBy retorna IGrouping<TKey, TElement>. Cada grupo tiene una Key (el valor de agrupación) y puedes iterarlo como una colección.
← LINQ: Where, Select, OrderByClases, Propiedades y Constructores →

Practica esta lección

Resuelve los ejercicios del curso de C# en la app, gratis y con corrección automática.

Empezar a practicar