How does GroupBy work in LINQ?

8

I'm having trouble understanding the GroupBy operator in LINQ.

    
asked by anonymous 26.08.2015 / 21:23

2 answers

10

GroupBy serves to group elements of according to a certain value in common between them. For example:

public class Fruta {
    public String Cor { get; set; }
    public String Nome { get; set; }
}

Suppose something like this:

var frutas = new List<Fruta>();

Suppose also that we put several fruits, with colors in common, and we want to group by the colors:

var grupos = frutas.GroupBy(f => f.Cor);

grupos is an object that implements IEnumerable<IGrouping<String, Fruta>> . That is, it is a list of group elements.

An object that implements IGrouping basically has two elements in its structure:

  • Key , that is, the key value of the grouping (in our case, the name of the fruit, a String );
  • GetEnumerator , that is, elements grouped by the key value. Here you can use the object directly, make a ToList() , use another Linq extension, etc, etc, etc.

Notice that it looks a lot like a dictionary.

If you want to print the groups' names, I can do this:

foreach (var nomeGrupo in grupos.Select(g => g.Key)) {
    Debug.WriteLine(nomeGrupo);
}

If you want to print the fruits of each group, I can do this:

foreach (var listaDeFrutasPorCor in grupos) {
    Debug.WriteLine("Imprimindo frutas da cor: " + listaDeFrutasPorCor.Key);
    Debug.WriteLine("-----------------------");
    foreach (var fruta in listaDeFrutasPorCor) {
        Debug.WriteLine(fruta.Nome);    
    }
}

I made a Fiddle here .

    
26.08.2015 / 21:31
5

As the name says, it groups data based on some criteria. It works the same or at least similarly to SQL%%.

With it you generate a dataset based on another set that must have some "column" repeated. You eliminate the repetition of this data.

Retired from documentation :

using System;
using System.Collections.Generic;
using System.Linq;

public class Program {
    public static void Main() {
        List<Pet> pets =
            new List<Pet>{ new Pet { Name="Barley", Age=8 },
                new Pet { Name="Boots", Age=4 },
                new Pet { Name="Whiskers", Age=1 },
                new Pet { Name="Daisy", Age=4 } };

        //está agrupando por idade e depois po nome.
        //Como existe dois pets com mesma idade eles serão agrupados
        var query = pets.GroupBy(pet => pet.Age, pet => pet.Name);

        foreach (var petGroup in query) {
            Console.WriteLine(petGroup.Key);
            foreach (var name in petGroup)
                Console.WriteLine("  {0}", name);
        }
    }
}

class Pet {
    public string Name { get; set; }
    public int Age { get; set; }
}

See working on dotNetFiddle .

    
26.08.2015 / 21:30