Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A group záradék objektumsorozatot IGrouping<TKey,TElement> ad vissza. A sorozat 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 karakter típusú. Minden IGrouping<TKey,TElement> objektum a tulajdonságában tárolja ezt a Key kulcsot. A fordító kikövetkezteti a kulcs típusát.
A C# nyelv referenciadokumentuma a C# nyelv legújabb kiadású verzióját ismerteti. Emellett a közelgő nyelvi kiadás nyilvános előzetes verziójú funkcióinak kezdeti dokumentációját is tartalmazza.
A dokumentáció azonosítja azokat a funkciókat, amelyeket először a nyelv utolsó három verziójában vagy az aktuális nyilvános előzetes verziókban vezetnek be.
Jótanács
Ha meg szeretné tudni, hogy mikor jelent meg először egy funkció a C#-ban, tekintse meg a C# nyelvi verzióelőzményeiről szóló cikket.
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 további lekérdezési műveleteket szeretne végrehajtani az egyes csoportokon, adjon meg egy ideiglenes azonosítót a környezeti kulcsszó használatával. Ha használja into, folytatnia kell a lekérdezést, és végül egy select mellékmondattal vagy egy másik group mellékmondattal 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álatára into-vel és into nélkül.
Csoport lekérdezés eredményeinek számbavétele
Mivel a IGrouping<TKey,TElement> lekérdezés által group előállított objektumok lényegében listák, beágyazott foreach ciklust kell használnia az egyes csoportok elemeinek eléréséhez. A külső hurok a csoportkulcsok felett iterál, a belső hurok pedig maga a csoport minden eleme felett iterál. Egy csoport rendelkezhet kulcssal, de elemekkel nem. Az alábbi foreach ciklus végrehajtja 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ő kódpéldák egy char-t használtak. Sztringkulcsot is megadhat, például a teljes vezetéknevet:
// 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 kulccsal egy bool értéket használ az eredmények két csoportra való felosztásához. Az érték a záradék egy group alkifejezéséből származik.
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. Metódushívási eredmény tárolására használja let , így nem kell 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 {temp} and {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 kulccsal szeretné csoportosítani az elemeket. Hozzon létre egy összetett kulcsot névtelen vagy névvel ellátott típussal a kulcselem tárolásához. Az alábbi példában tegyük fel, hogy egy osztálynak Person neve és cityneve surname van. A group záradék külön csoportot hoz létre minden olyan személycsoport számára, akik ugyanazt a vezetéknevet és várost viselik.
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 olyan szerkezetet is, amely nem követeli meg szigorúan ezeket a metódus-felülbírálásokat. 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.
Példák
Az alábbi példa bemutatja a forrásadatok csoportokba rendelésének szabványos mintáját, ha nem alkalmaz további lekérdezési logikát a csoportokra. Ezt a mintát folytatás nélküli csoportosításnak nevezzük. A példa a sztringek tömbjének elemeit az első betűjüknek megfelelően csoportosítja. 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. Az egyes visszaadott csoportok egyes elemeinek eléréséhez használjon beágyazott hurkot foreach a cikluson belül, amely iterálja a csoportkulcsokat, ahogy 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 '{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
*/
Az alábbi példa bemutatja, hogyan hajthat végre további logikát a csoportokon a létrehozásuk után egy folytatás használatával into. További információért lásd into. 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: {wordGroup.Key}");
foreach (var word in wordGroup)
{
Console.WriteLine($" {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
*/
Fordításkor a fordító záradékokat group fordít le a metódushoz intézett GroupBy hívásokra.
A záradékos lekérdezés szintaxisa group nem támogatja az egyéni egyenlőség-összehasonlítót. Ha a lekérdezésben szeretné használni IEqualityComparer , használja kifejezetten a metódust GroupBy .