cláusula de agrupar (translation from VPE for Csharp Reference)

The group cláusula retorna uma sequência de IGrouping<TKey, TElement> objetos que contêm zero ou mais itens que correspondem ao valor de chave para o agrupar. Por exemplo, você pode agrupar uma sequência de seqüências de caracteres de acordo com a primeira letra de cada sequência de caracteres.Nesse caso, a primeira letra é a chave e tem um tipo de chare é armazenado na Key propriedade de cada IGrouping<TKey, TElement> objeto. O compilador infere o tipo da chave.

Você pode finalizar uma expressão de consulta com um group cláusula, sistema autônomo mostrado no exemplo a seguir:

// Query variable is an IEnumerable<IGrouping<char, Student>>
var studentQuery1 =
    from student in students
    group student by student.Last[0];

Se você quiser realizar operações de consulta adicionais em cada agrupar, você pode especificar um identificador temporário usando o empalavra- chave contextual.Quando você usa into, você deve continuar com a consulta e eventualmente encerrá-lo com um um select demonstrativo ou outro group cláusula, conforme mostrado no trecho a seguir:

// Group students by the first letter of their last name
// Query variable is an IEnumerable<IGrouping<char, Student>>
var studentQuery2 =
    from student in students
    group student by student.Last[0] into g
    orderby g.Key
    select g;

Exemplos do uso de mais concluídagroup com e sem into são fornecidas na seção exemplo deste tópico.

Enumerando os resultados de uma consulta de agrupar

Porque o IGrouping<TKey, TElement> objetos produzidos por um group consulta são essencialmente uma lista de listas, você deve usar um aninhados foreach loop para acesso os itens de cada agrupar.O loop externo itera sobre as chaves de agrupar e o loop interno itera sobre cada item do agrupar propriamente dito.Um agrupar pode ter uma chave, mas nenhum elemento.Este é o foreach loop que executa a consulta nos exemplos de código anteriores:

// Iterate group items with a nested foreach. This IGrouping encapsulates
// a sequence of Student objects, and a Key of type char.
// For convenience, var can also be used in the foreach statement.
foreach (IGrouping<char, Student> studentGroup in studentQuery2)
{
     Console.WriteLine(studentGroup.Key);
     // Explicit type for student could also be used here.
     foreach (var student in studentGroup)
     {
         Console.WriteLine("   {0}, {1}", student.Last, student.First);
     }
 }

chave Tipos

Chaves de agrupar podem ser qualquer tipo, sistema autônomo uma cadeia de caracteres, um tipo numérico interno ou definido pelo usuário denominado tipo ou tipo anônimo.

agrupamento pela seqüência de caracteres

Os exemplos de código anterior usado um char. Uma chave de seqüência de caracteres poderia com com facilidade foram especificada em vez disso, por exemplo o último nome completo:

// Same as previous example except we use the entire last name as a key.
// Query variable is an IEnumerable<IGrouping<string, Student>>
 var studentQuery3 =
     from student in students
     group student by student.Last;

agrupamento por bool

O exemplo a seguir mostra o uso de um valor booleano para uma chave dividir os resultados em dois grupos.Observe que o valor é produzido por uma subexpressão no group cláusula.

class GroupSample1
{
    // The element type of the data source.
    public class Student
    {
        public string First { get; set; }
        public string Last { get; set; }
        public int ID { get; set; }
        public List<int> Scores;
    }

    public static List<Student> GetStudents()
    {
        // Use a collection initializer to create the data source. Note that each element
        //  in the list contains an inner sequence of scores.
        List<Student> students = new List<Student>
        {
           new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81, 60}},
           new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}},
           new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91, 95}},
           new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}},
           new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}} 
        };

        return students;

    }

    static void Main()
    {
        // Obtain the data source.
        List<Student> students = GetStudents();

        // Group by true or false.
        // Query variable is an IEnumerable<IGrouping<bool, Student>>
        var booleanGroupQuery =
            from student in students
            group student by student.Scores.Average() >= 80; //pass or fail!

        // Execute the query and access items in each group
        foreach (var studentGroup in booleanGroupQuery)
        {
            Console.WriteLine(studentGroup.Key == true ? "High averages" : "Low averages");
            foreach (var student in studentGroup)
            {
                Console.WriteLine("   {0}, {1}:{2}", student.Last, student.First, student.Scores.Average());
            }
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
  Low averages
   Omelchenko, Svetlana:77.5
   O'Donnell, Claire:72.25
   Garcia, Cesar:75.5
  High averages
   Mortensen, Sven:93.5
   Garcia, Debra:88.25
*/

agrupamento pelo intervalo numérico

O próximo exemplo utiliza uma expressão para criar chaves de agrupar numérico que representam uma faixa percentil.Observe o uso de permitir que sistema autônomo um local conveniente para armazenar um método chamar resultado, para que não é necessário chamar o método duas vezes no group cláusula. Observação também o groupcláusula que para evitar uma exceção de "divisão por zero" o código verifica para ter certeza de que o aluno não possui uma média igual a zero. Para obter mais informações sobre como usar métodos com segurança em expressões de consulta, consulte Como: Tratar exceções em expressões de consulta (guia de programação translation from VPE for Csharp).

class GroupSample2
{
    // The element type of the data source.
    public class Student
    {
        public string First { get; set; }
        public string Last { get; set; }
        public int ID { get; set; }
        public List<int> Scores;
    }

    public static List<Student> GetStudents()
    {
        // Use a collection initializer to create the data source. Note that each element
        //  in the list contains an inner sequence of scores.
        List<Student> students = new List<Student>
        {
           new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81, 60}},
           new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}},
           new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91, 95}},
           new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}},
           new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}} 
        };

        return students;

    }

    // This method groups students into percentile ranges based on their
    // grade average. The Average method returns a double, so to produce a whole
    // number it is necessary to cast to int before dividing by 10. 
    static void Main()
    {
        // Obtain the data source.
        List<Student> students = GetStudents();

        // Write the query.
        var studentQuery =
            from student in students
            let avg = (int)student.Scores.Average()
            group student by (avg == 0 ? 0 : avg / 10) into g
            orderby g.Key
            select g;            

        // Execute the query.
        foreach (var studentGroup in studentQuery)
        {
            int temp = studentGroup.Key * 10;
            Console.WriteLine("Students with an average between {0} and {1}", temp, temp + 10);
            foreach (var student in studentGroup)
            {
                Console.WriteLine("   {0}, {1}:{2}", student.Last, student.First, student.Scores.Average());
            }
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
     Students with an average between 70 and 80
       Omelchenko, Svetlana:77.5
       O'Donnell, Claire:72.25
       Garcia, Cesar:75.5
     Students with an average between 80 and 90
       Garcia, Debra:88.25
     Students with an average between 90 and 100
       Mortensen, Sven:93.5
 */

Agrupando por chaves compostas

Use uma chave composta quando desejar agrupar elementos de acordo com a mais de uma chave.Você criar uma chave composta usando um tipo anônimo ou um tipo nomeado para conter o elemento-chave.O exemplo a seguir, suponha que uma classe Person ter sido declarado com membros chamados surname e city. The group cláusula faz com que um agrupar separado seja criado para cada conjunto de pessoas com o mesmo sobrenome e da mesma cidade.

group person by new {name = person.surname, city = person.city};

Use um tipo nomeado se você deve passar a variável de consulta para outro método.Criar uma classe especial usando as propriedades implementadas automaticamente para as chaves e, em seguida, substituir o Equals e GetHashCode métodos. Você também pode usar uma struct, caso em que não é estritamente necessário que substituir esses métodos.Para obter mais informações, consulte Como: Implementar uma classe leve com propriedades implementado auto (guia de programação translation from VPE for Csharp) e Como: Consulta de arquivos de duplicados em uma árvore de diretório (LINQ).O último tópico possui um exemplo de código que demonstra como usar uma chave composta com um tipo nomeado.

Exemplo

O exemplo a seguir mostra o padrão para solicitar dados de fonte em grupos quando nenhuma lógica de consulta adicionais é aplicada a grupos.Isso é chamado de um agrupamento sem uma continuação.Os elementos em uma matriz de seqüências de caracteres são agrupados de acordo com sua primeira letra.O resultado da consulta é um IGrouping<TKey, TElement> tipo que contém um público Key propriedade do tipo char e um IEnumerable<T> coleção que contém o agrupamento de cada item.

O resultado de um group cláusula é uma sequência de seqüências. Portanto, para acessar sistema autônomo elementos individuais dentro de cada agrupar retornado, use um aninhados foreach loop dentro do loop que itere sistema autônomo chaves de agrupar, conforme mostrado no exemplo a seguir.

class GroupExample1
{
    static void Main()
    {
        // Create a data source.
        string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" };

        // Create the query.
        var wordGroups =
            from w in words
            group w by w[0];

        // Execute the query.
        foreach (var wordGroup in wordGroups)
        {
            Console.WriteLine("Words that start with the letter '{0}':", wordGroup.Key);
            foreach (var word in wordGroup)
            {
                Console.WriteLine(word);
            }
        }

        // Keep the console window open in debug mode
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }        
}
/* Output:
      Words that start with the letter 'b':
        blueberry
        banana
      Words that start with the letter 'c':
        chimpanzee
        cheese
      Words that start with the letter 'a':
        abacus
        apple
     */

Este exemplo mostra como executar lógica adicional nos grupos após a criação, usando um continuação with into. Para obter mais informações, consulte em (translation from VPE for Csharp Reference).O exemplo a seguir pesquisa cada agrupar para selecionar somente aqueles cujo valor é uma vogal.

class GroupClauseExample2
{
    static void Main()
    {
        // Create the data source.
        string[] words2 = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese", "elephant", "umbrella", "anteater" };

        // Create the query.
        var wordGroups2 =
            from w in words2
            group w by w[0] into grps
            where (grps.Key == 'a' || grps.Key == 'e' || grps.Key == 'i'
                   || grps.Key == 'o' || grps.Key == 'u')
            select grps;

        // Execute the query.
        foreach (var wordGroup in wordGroups2)
        {
            Console.WriteLine("Groups that start with a vowel: {0}", wordGroup.Key);
            foreach (var word in wordGroup)
            {
                Console.WriteLine("   {0}", word);
            }
        }

        // Keep the console window open in debug mode
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Groups that start with a vowel: a
        abacus
        apple
        anteater
    Groups that start with a vowel: e
        elephant
    Groups that start with a vowel: u
        umbrella
*/    

Comentários

No momento da compilar, group as cláusulas são traduzidas em chamadas para o GroupBy método.

Consulte também

Tarefas

Como: Um agrupar (guia de programação translation from VPE for Csharp) de agrupar

Como: Resultados do agrupar de várias maneiras (guia de programação translation from VPE for Csharp)

Como: Executar uma subconsulta em uma operação de agrupamento (guia de programação translation from VPE for Csharp)

Conceitos

Expressões de consulta do LINQ (guia de programação translation from VPE for Csharp)

Referência

IGrouping<TKey, TElement>

GroupBy

ThenBy

ThenByDescending

Outros recursos

Palavras-chave de consulta (translation from VPE for Csharp Reference)