group tümcesi (C# Başvurusu)

groupYan tümcesi, IGrouping<TKey,TElement> Grup için anahtar değeriyle eşleşen sıfır veya daha fazla öğe içeren bir nesne dizisi döndürür. Örneğin, her bir dizedeki ilk harfe göre bir dizi dizeyi gruplandırabilirsiniz. Bu durumda, ilk harf anahtardır ve bir tür chariçerir ve Key her nesnenin özelliğinde saklanır IGrouping<TKey,TElement> . Derleyici, anahtarın türünü haller.

groupAşağıdaki örnekte gösterildiği gibi bir sorgu ifadesini yan tümcesiyle sona erdirmek için:

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

Her grupta ek sorgu işlemleri gerçekleştirmek istiyorsanız, ' ın bağlamsal anahtar sözcüğünü kullanarak geçici bir tanımlayıcı belirtebilirsiniz. into' I kullandığınızda sorgu ile devam etmeniz ve sonunda select aşağıdaki alıntıda gösterildiği gibi bir deyimi ya da başka bir yan tümcesini sona erdirmek gerekir group :

// 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;

groupBu makalenin örnek bölümünde ile ve olmadan kullanımı için daha kapsamlı örnekler verilmiştir into .

Bir grup sorgusunun sonuçlarını numaralandırma

IGrouping<TKey,TElement>Bir sorgu tarafından üretilen nesneler group temelde bir liste listesi olduğundan, her bir gruptaki öğelere erişmek için iç içe geçmiş bir foreach döngüsü kullanmanız gerekir. Dış döngü grup anahtarlarının üzerinde yinelenir ve iç döngü gruptaki her öğe için yinelenir. Bir grupta anahtar olabilir ancak öğe yok. Aşağıda, foreach önceki kod örneklerinde sorguyu yürüten döngü verilmiştir:

// 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);
     }
 }

Anahtar türleri

Grup anahtarları dize, yerleşik bir sayısal tür veya Kullanıcı tanımlı adlandırılmış tür veya anonim tür gibi herhangi bir tür olabilir.

Dizeye göre gruplandırma

Önceki kod örnekleri bir kullanır char . Bunun yerine bir dize anahtarı kolayca belirtilmelidir, örneğin, son soyadı adı:

// 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;

Bool ile gruplandırma

Aşağıdaki örnek, sonuçları iki gruba bölmek için bir anahtar için bool değer kullanımını gösterir. Değerin yan tümce içindeki bir alt ifade tarafından üretildiğini unutmayın group .

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
*/

Sayısal aralığa göre gruplandırma

Sonraki örnek, bir yüzdebirlik aralığını temsil eden sayısal grup anahtarları oluşturmak için bir ifade kullanır. Bir yöntem çağrı sonucunu depolamak için uygun bir konum olarak izin ver öğesinin kullanımını unutmayın. bu sayede yöntemi yan tümcesinde iki kez çağırmak zorunda kalmazsınız group . Sorgu ifadelerinde yöntemleri güvenle kullanma hakkında daha fazla bilgi için bkz. sorgu ifadelerinde özel durumları işleme.

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 / 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
 */

Bileşik anahtarlara göre gruplandırma

Öğeleri birden fazla anahtara göre gruplandırmak istediğinizde bileşik anahtar kullanın. Anahtar öğesini tutmak için anonim bir tür veya adlandırılmış bir tür kullanarak bileşik anahtar oluşturursunuz. Aşağıdaki örnekte, bir sınıfının Person ve adlı üyelerle bildirildiği varsayılır surname city . groupYan tümcesi, aynı soyadı ve aynı şehirde bulunan her kişi kümesi için ayrı bir grup oluşturulmasına neden olur.

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

Sorgu değişkenini başka bir yönteme geçirmeniz gerekiyorsa adlandırılmış bir tür kullanın. Anahtarlar için otomatik uygulanan özellikler kullanarak özel bir sınıf oluşturun ve ardından Equals ve yöntemlerini geçersiz kılın GetHashCode . Ayrıca, bu yöntemleri kesin bir şekilde geçersiz kılmak zorunda değilsiniz bir yapı da kullanabilirsiniz. Daha fazla bilgi için bkz. Otomatik uygulanan özelliklerle hafif bir sınıf uygulama ve bir dizin ağacındaki yinelenen dosyaları sorgulama. İkinci makalede, adlandırılmış tür ile bileşik anahtarın nasıl kullanılacağını gösteren bir kod örneği bulunur.

Örnek 1

Aşağıdaki örnek, gruplara ek sorgu mantığı uygulanırken kaynak verileri gruplara sıralamak için standart düzeni gösterir. Bu, devamlılık olmadan gruplandırma olarak adlandırılır. Dizeler dizisindeki öğeler, ilk harfine göre gruplandırılır. Sorgunun sonucu, IGrouping<TKey,TElement> türünde public bir Key özelliği char ve IEnumerable<T> gruplandırmadaki her öğeyi içeren bir koleksiyonu içeren bir türdür.

groupYan tümcesinin sonucu bir dizi dizidir. Bu nedenle, döndürülen her grup içindeki ayrı öğelere erişmek için, foreach Aşağıdaki örnekte gösterildiği gibi, döngü içinde grup anahtarlarını yineleyen iç içe bir döngü kullanın.

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
     */

Örnek 2

Bu örnek, ile devam eden kullanarak gruplar üzerinde nasıl ek mantık gerçekleştirileceğini gösterir into . Daha fazla bilgi için bkz .. Aşağıdaki örnek, her bir grubu yalnızca anahtar değerini bir sesli harf olarak seçmek üzere sorgular.

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
*/

Açıklamalar

Derleme zamanında, group yan tümceler yöntemine yapılan çağrılara çevrilir GroupBy .

Ayrıca bkz.