Grupo LINQPor

Resumo : neste tutorial, você aprenderá como usar o GroupBy()método LINQ para agrupar os elementos de uma sequência com base em uma chave.

O GroupBy()método agrupa elementos em uma sequência com base em uma chave especificada. O método retorna uma sequência de grupos, onde cada elemento implementa a IGrouping(TKey, TElement>interface.

O GroupBy()método possui diversas sobrecargas e cada uma tem uma finalidade específica. Apresentaremos algumas das GroupBy()sobrecargas com exemplos.

Um método LINQ GroupBy() simples

Aqui está a sintaxe do GroupBy()método:

IGrouping<TKey,TElement> GroupBy<TSource, TKey>(
    IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector
);Linguagem de código:  C#  ( cs )

Nesta sintaxe:

  • TSourceé o tipo de elementos da sequência de origem.
  • TKeyé a chave retornada pela keySelectorfunção.
  • TElementé o tipo de elementos no IGrouping<TKey, TElement>.
  • sourceé a sequência de entrada que possui o IEnumerable<TSource>.
  • keySelectoré uma função que seleciona a chave para cada elemento.
  • elementSelectoré uma função que mapeia cada elemento para um elemento em IGrouping< TKey, TElement>.

O GroupBy()método by retorna uma sequência de elementos com o tipo IGrouping<TKey, TElement>.

O exemplo a seguir usa o GroupBy()método para agrupar uma lista de alunos em grupos especificados pelos cursos dos alunos:

class Student
{
    public string? Name { get; set; }
    public string? Course { get; set; }
    public int Age { get; set; }

}

class Program
{
    public static void Main(string[] args)
    {

        // Create a list of students
        var students = new List<Student>()
        {
            new Student { Name = "John", Course = "C#", Age = 25 },
            new Student { Name = "Jane", Course = "C#", Age = 22 },
            new Student { Name = "Bob", Course = "Javascript", Age = 20 },
            new Student { Name = "Alice", Course = "Javascript", Age = 21 }
        };

        // Group the students by course
        var groups = students.GroupBy(s => s.Course);

        // Show the groups
        foreach (var group in groups)
        {
            Console.WriteLine(group.Key + ":");
            foreach (var student in group)
            {
                Console.WriteLine("- " + student.Name + " (" + student.Age + ")");
            }
            Console.WriteLine();
        }

    }
}Linguagem de código:  C#  ( cs )

Saída:

C#:
- John (25)
- Jane (22)

Javascript:
- Bob (20)
- Alice (21)Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina uma Studentclasse que tenha três propriedades Name,, Coursee Age:

class Student
{
    public string? Name { get; set; }
    public string? Course { get; set; }
    public int Age { get; set; }
}Linguagem de código:  C#  ( cs )

Segundo, crie uma lista que contenha quatro Studentobjetos:

var students = new List<Student>()
{
    new Student { Name = "John", Course = "C#", Age = 25 },
    new Student { Name = "Jane", Course = "C#", Age = 22 },
    new Student { Name = "Bob", Course = "Javascript", Age = 20 },
    new Student { Name = "Alice", Course = "Javascript", Age = 21 }
};Linguagem de código:  C#  ( cs )

Terceiro, use o GroupBy()método para agrupar os alunos por cursos:

var groups = students.GroupBy(s => s.Course);Linguagem de código:  C#  ( cs )

Por fim, mostre os grupos ao Console:

foreach (var group in groups)
{
    Console.WriteLine(group.Key + ":");
    foreach (var student in group)
    {
        Console.WriteLine("- " + student.Name + " (" + student.Age + ")");
    }
    Console.WriteLine();
}Linguagem de código:  C#  ( cs )

Usando o método LINQ GroupBy() com um seletor de elemento

A seguinte sobrecarga do GroupBy()método possui um segundo delegado que permite selecionar os elementos dos grupos:

IGrouping<TKey,TElement> GroupBy<TSource, TKey, TElement>(
   IEnumerable<TSource> source, 
   Func<TSource, TKey> keySelector, 
   Func<TSource, TElement> elementSelector
);Linguagem de código:  C#  ( cs )

Por exemplo:

using static System.Console;
class Student
{
    public string? Name { get; set; }
    public string? Course { get; set; }
    public int Age { get; set; }
}
class Program
{
    public static void Main(string[] args)
    {

        // Create a list of students
        var students = new List<Student>()
        {
            new Student { Name = "John", Course = "C#", Age = 25 },
            new Student { Name = "Jane", Course = "C#", Age = 22 },
            new Student { Name = "Bob", Course = "Javascript", Age = 20 },
            new Student { Name = "Alice", Course = "Javascript", Age = 21 }
        };

        // Group the students by course
        var groups = students.GroupBy(s => s.Course, s=> s.Name);

        // Show the groups
        foreach (var group in groups)
        {
            WriteLine($"{group.Key}:");
            foreach (var name in group)
            {
                WriteLine($"- {name}");
            }
            WriteLine();
        }

    }
}Linguagem de código:  C#  ( cs )

Saída:

C#:
- John
- Jane

Javascript:
- Bob
- AliceLinguagem de código:  C#  ( cs )

Neste exemplo, usamos a elementSelectorfunção para selecionar os elementos de cada grupo. Mais especificamente, selecionamos o nome de cada aluno como elemento da sequência de resultados.

Usando o método LINQ GroupBy() com um comparador de igualdade

A seguinte sobrecarga do GroupBy()método permite que você especifique uma instância IEqualityComparer<TKey>para comparar chaves quanto à igualdade:

IGrouping<TKey,TElement> GroupBy<TSource, TKey, TElement>(
   IEnumerable<TSource> source, 
   Func<TSource, TKey> keySelector, 
   Func<TSource, TElement> elementSelector,
   IEqualityComparer<TKey>? comparer
);Linguagem de código:  C#  ( cs )

Essa sobrecarga é útil quando você deseja ter um comparador de igualdade específico que se adapte ao seu cenário.

Por exemplo, o seguinte usa o GroupBy()método com um CourseComparer que compara dois cursos sem distinção entre maiúsculas e minúsculas:

using static System.Console;
class Student
{
    public string? Name { get; set; }
    public string? Course { get; set; }
    public int Age { get; set; }
}

class CourseComparer : IEqualityComparer<string?>
{
    public bool Equals(string? x, string? y)
    {
        if (x == null || y == null)
            return false;

        return x.ToLower() == y.ToLower();
    }

    public int GetHashCode(string obj)
    {
        return obj.ToLower().GetHashCode();
    }
}

class Program
{
    public static void Main(string[] args)
    {

        // Create a list of students
        var students = new List<Student>()
        {
            new Student { Name = "John", Course = "C#", Age = 25 },
            new Student { Name = "Jane", Course = "c#", Age = 22 },
            new Student { Name = "Bob", Course = "Javascript", Age = 20 },
            new Student { Name = "Alice", Course = "JAVASCRIPT", Age = 21 }
        };

        var groups = students.GroupBy(s => s.Course, new CourseComparer());

        // Display the groups
        foreach (var group in groups)
        {
            WriteLine($"{group.Key}:");
            foreach (var student in group)
            {
                WriteLine($"- {student.Name} ({student.Age})");

            }
            WriteLine();
        }

    }
}Linguagem de código:  C#  ( cs )

Saída:

C#:
- John (25)
- Jane (22)

Javascript:
- Bob (20)
- Alice (21)Linguagem de código:  C#  ( cs )

Neste exemplo, os nomes dos cursos não são padronizados. Alguns cursos estão em letras maiúsculas, enquanto outros não:

var students = new List<Student>()
{
    new Student { Name = "John", Course = "C#", Age = 25 },
    new Student { Name = "Jane", Course = "c#", Age = 22 },
    new Student { Name = "Bob", Course = "Javascript", Age = 20 },
    new Student { Name = "Alice", Course = "JAVASCRIPT", Age = 21 }
};Linguagem de código:  C#  ( cs )

A CourseComparerclasse compara dois cursos sem distinção entre maiúsculas e minúsculas, convertendo-os para letras minúsculas antes da comparação:

class CourseComparer : IEqualityComparer<string?>
{
    public bool Equals(string? x, string? y)
    {
        if (x == null || y == null)
            return false;

        return x.ToLower() == y.ToLower();
    }

    public int GetHashCode(string obj)
    {
        return obj.ToLower().GetHashCode();
    }
}Linguagem de código:  C#  ( cs )

O GroupBy()método usa uma instância de CourseComparerpara agrupar os alunos pelos nomes dos cursos:

 var groups = students.GroupBy(s => s.Course, new CourseComparer());Linguagem de código:  C#  ( cs )

Resumo

  • Use o GroupBy()método LINQ para agrupar elementos em uma sequência em grupos por uma chave especificada.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *