Megosztás a következőn keresztül:


csoport záradék (C# referencia)

A group záradék olyan objektumsorozatot IGrouping<TKey,TElement> ad vissza, amely nulla vagy több olyan elemet tartalmaz, amely megfelel a csoport kulcsértékének. A sztringek sorozatát például az egyes sztringek első betűje szerint csoportosíthatja. Ebben az esetben az első betű a kulcs, és típus karakterrel rendelkezik, és az Key egyes IGrouping<TKey,TElement> objektumok tulajdonságában van tárolva. A fordító a kulcs típusát jelzi.

A lekérdezési kifejezéseket záradékkal group zárhatja le, ahogyan az alábbi példában is látható:

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

Ha az egyes csoportokon további lekérdezési műveleteket szeretne végrehajtani, a környezeti kulcsszó használatával megadhat egy ideiglenes azonosítót. Ha használjainto, folytatnia kell a lekérdezést, és végül egy utasítással vagy egy másik group záradékkal select kell befejeznie, ahogyan az alábbi részletben látható:

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

A cikk Példa szakaszában további teljes példákat talál a group használatukról into .

Csoport lekérdezés eredményeinek számbavétele

Mivel a IGrouping<TKey,TElement> lekérdezés által group létrehozott objektumok lényegében listák listája, az egyes csoportok elemeinek eléréséhez beágyazott foreach hurkot kell használnia. A külső hurok a csoportkulcsok felett iterál, a belső hurok pedig maga a csoport minden eleme felett iterál. Előfordulhat, hogy egy csoport rendelkezik kulcssal, de nem rendelkezik elemekkel. Az alábbi foreach ciklus hajtja végre a lekérdezést az előző kód példákban:

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

Kulcstípusok

A csoportkulcsok bármilyen típusúak lehetnek, például sztringek, beépített numerikus típus, felhasználó által definiált névvel ellátott típus vagy névtelen típus.

Csoportosítás sztring szerint

Az előző példakód egy char. Ehelyett egyszerűen megadható egy sztringkulcs, például a teljes vezetéknév:

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

Csoportosítás bool szerint

Az alábbi példa egy kulcs bool értékének használatát mutatja be az eredmények két csoportra való felosztásához. Vegye figyelembe, hogy az értéket a záradék egy alkifejezése group hozza létre.

class GroupSample1
{
    // The element type of the data source.
    public class Student
    {
        public required string First { get; init; }
        public required string Last { get; init; }
        public required int ID { get; init; }
        public required 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 Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= [97, 72, 81, 60]},
           new Student {First="Claire", Last="O'Donnell", ID=112, Scores= [75, 84, 91, 39]},
           new Student {First="Sven", Last="Mortensen", ID=113, Scores= [99, 89, 91, 95]},
           new Student {First="Cesar", Last="Garcia", ID=114, Scores= [72, 81, 65, 84]},
           new Student {First="Debra", Last="Garcia", ID=115, Scores= [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());
            }
        }
    }
}
/* 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
*/

Csoportosítás numerikus tartomány szerint

A következő példa egy kifejezéssel hoz létre numerikus csoportkulcsokat, amelyek egy percentilis tartományt jelölnek. Vegye figyelembe, hogy a Let egy kényelmes hely a metódushívás eredményének tárolására, hogy ne kelljen kétszer meghívnia a metódust a group záradékban. A metódusok lekérdezési kifejezésekben való biztonságos használatáról további információt a lekérdezési kifejezések kivételeinek kezelése című témakörben talál.

class GroupSample2
{
    // The element type of the data source.
    public class Student
    {
        public required string First { get; init; }
        public required string Last { get; init; }
        public required int ID { get; init; }
        public required 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 Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= [97, 72, 81, 60]},
           new Student {First="Claire", Last="O'Donnell", ID=112, Scores= [75, 84, 91, 39]},
           new Student {First="Sven", Last="Mortensen", ID=113, Scores= [99, 89, 91, 95]},
           new Student {First="Cesar", Last="Garcia", ID=114, Scores= [72, 81, 65, 84]},
           new Student {First="Debra", Last="Garcia", ID=115, Scores= [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());
            }
        }
    }
}
/* 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
 */

Csoportosítás összetett kulcsok szerint

Összetett kulcsot akkor használjon, ha több kulcs szerint szeretné csoportosítani az elemeket. A kulcselem tárolásához névtelen vagy névvel ellátott típussal hozhat létre összetett kulcsot. Az alábbi példában tegyük fel, hogy egy osztályt Person deklaráltak a nevesített surname és citya . A group záradék egy külön csoportot hoz létre minden olyan személycsoport számára, aki ugyanazzal a vezetéknévvel és ugyanazzal a várossal rendelkezik.

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

Használjon elnevezett típust, ha a lekérdezési változót egy másik metódusnak kell átadnia. Hozzon létre egy speciális osztályt a kulcsok automatikusan implementált tulajdonságaival, majd felülbírálja a metódusokat és GetHashCode a Equals metódusokat. Használhat egy szerkezetet is, amely esetben nem kell szigorúan felülbírálnia ezeket a módszereket. További információ : Hogyan implementálhat egy egyszerűsített osztályt automatikusan implementált tulajdonságokkal , és hogyan kérdezhet le duplikált fájlokat egy könyvtárfán. Az utóbbi cikk egy kód példáját mutatja be, amely bemutatja, hogyan használható egy összetett kulcs nevesített típussal.

1. példa

Az alábbi példa a forrásadatok csoportokba rendelésének szabványos mintáját mutatja be, ha a rendszer nem alkalmaz további lekérdezési logikát a csoportokra. Ezt folytatás nélküli csoportosításnak nevezzük. A sztringtömb elemei az első betűjük szerint vannak csoportosítva. A lekérdezés eredménye egy IGrouping<TKey,TElement> olyan típus, amely egy nyilvános Key típusú char tulajdonságot és egy gyűjteményt IEnumerable<T> tartalmaz, amely a csoportosítás minden elemét tartalmazza.

A záradék eredménye group szekvenciák sorozata. Ezért az egyes visszaadott csoportok egyes elemeinek eléréséhez használjon beágyazott hurkot foreach a hurokban, amely iterálja a csoportkulcsokat, ahogyan az az alábbi példában látható.

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

2. példa

Ez a példa bemutatja, hogyan hajthat végre további logikát a csoportokon a létrehozásuk után egy folytatás használatávalinto. További információ: Az alábbi példa lekérdezi az egyes csoportokat, hogy csak azokat válassza ki, amelyek kulcsértéke magánhangzó.

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

Megjegyzések

Fordításkor a group záradékok a metódus hívásaiká GroupBy lesznek lefordítva.

Lásd még