group — Klauzula (odwołanie w C#)
group Klauzuli zwraca ciąg IGrouping obiektów, które zawierają zera lub więcej elementów, które pasują do wartości klucza dla grupy.Na przykład można grupować sekwencji ciągi w pierwszej litery każdego ciągu.W tym przypadku pierwsza litera jest kluczem i ma typ chari jest przechowywany w Key właściwości każdego IGrouping obiektu.Typ klucza jest ustalany przez kompilator.
Można zakończyć w wyrażeniu kwerendy z group klauzuli, jak pokazano w następującym przykładzie:
// Query variable is an IEnumerable<IGrouping<char, Student>>
var studentQuery1 =
from student in students
group student by student.Last[0];
Jeśli chcesz wykonywać operacje dodatkowych kwerend na każdej grupy można określić identyfikator tymczasowych przy użyciu do kontekstowe słowa kluczowego.Kiedy używać into, musi kontynuować kwerendy i ostatecznie zakończyć z albo select instrukcji lub w innym group klauzuli, jak pokazano w poniższym fragmencie:
// 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;
Zakończenie więcej przykładów użycia group z i bez into są podane w sekcji przykład tego tematu.
Wyliczanie wyników kwerendy grupy
Ponieważ IGrouping przedmioty produkowane przez group kwerendy są zasadniczo lista listy, należy użyć zagnieżdżonych foreach pętli, dostęp do elementów w każdej grupie.Zewnętrzna pętla wykonuje iterację przez klucze grup i wewnętrzna pętla wykonuje iterację przez każdego elementu w samej grupy.Grupa może mieć kluczem, ale nie elementy.Oto foreach pętli, który wykonuje kwerendę w poprzednich przykładach kodu:
// 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);
}
}
Typy kluczy
Klucze grup mogą być dowolnego typu, takie jak ciąg znaków, typu liczbowego wbudowanych lub przez użytkownika o nazwie typu lub anonimowe.
Grupowanie według ciąg
Poprzednie przykłady kodu używany char.Ciągu klucza może łatwo zostały określone zamiast tego, na przykład pełne nazwisko:
// 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;
Grupowanie według bool
W poniższym przykładzie pokazano sposób użycia wartość bool klucza podzielić na dwie grupy wyników.Należy zauważyć, że wartość jest produkowany przez wyrażenia podrzędnego w group klauzuli.
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
*/
Grupowanie według zakresu numeryczne
W następnym przykładzie użyto wyrażenia do tworzenia kluczy numerycznych grupy, które reprezentuje zakres wartości percentylu.Uwaga Użycie Niech jako wygodną lokalizacją do przechowywania metody wywołania wynik, tak, aby nie trzeba wywołać metodę dwa razy w group klauzuli.Należy zwrócić uwagę, również w group klauzulę, że aby uniknąć wyjątek "dzielenie przez zero" kod sprawdza upewnić się, że uczeń nie ma średnią równą zero.Aby uzyskać więcej informacji na temat bezpiecznego używania metod w wyrażeniach kwerend, zobacz Porady: obsługa wyjątków w wyrażeniach kwerend (Przewodnik programowania w języku C#).
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
*/
Grupowanie według kluczy kompozytowe
Za pomocą klucza złożonego chcesz elementy grupy, zgodnie z więcej niż jednego klawisza.Można utworzyć klucz złożony za pomocą typ anonimowy lub typ nazwany do przechowywania kluczowym elementem.W poniższym przykładzie założono, że klasa Person została zadeklarowana z członków o nazwie surname i city.group Klauzuli powoduje, że oddzielne grupy ma być utworzony dla każdego zestawu osoby o to samo nazwisko i tym samym mieocie.
group person by new {name = person.surname, city = person.city};
Jeśli zmienna kwerendy musi przekazać do innej metody, należy użyć typu nazwanego.Utworzyć specjalną klasę przy użyciu właściwości auto wdrożone dla kluczy, a następnie zastąpić Equals i GetHashCode metody.Można również użyć struct, w którym to przypadku ściśle trzeba zastąpić te metody.Aby uzyskać więcej informacji, zobacz Porady: implementowanie klasy lekkiej przy użyciu automatycznie implementowanych właściwości (Przewodnik programowania w języku C#) i Porady: zapytanie o zduplikowane pliki w drzewie katalogu (LINQ).Ten ostatni temat zawiera przykładowy kod, który demonstruje, jak użyć klucza złożonego z nazwanym typem.
Przykład
Poniższy przykład pokazuje wzorzec standardowy do porządkowania danych źródłowych w grupach po logiki nie dodatkowych kwerend jest stosowane do grup.Jest to nazywane grupowania bez kontynuacji.Elementy w tablicy ciągów są grupowane zgodnie z ich pierwszej litery.Wynik kwerendy jest IGrouping typu, który zawiera publicznego Key właściwość typu char i IEnumerable kolekcji, która zawiera każdego elementu w zgrupowania.
Wynik group klauzuli jest sekwencją sekwencji.W związku z tym, aby uzyskać dostęp do poszczególnych elementów w obrębie każdej grupy zwracane, użyj zagnieżdżonych foreach pętli wewnątrz pętli, która wykonuje iteracje klucze grup, jak pokazano w poniższym przykładzie.
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
*/
W tym przykładzie pokazuje, jak przeprowadzić dodatkowe logikę w grupach po ich utworzeniu, za pomocą kontynuacji z into.Aby uzyskać więcej informacji, zobacz into (odwołanie w C#).Poniższy przykład kwerendy każdej grupy, zaznacz tylko te, których wartość klucza jest samogłoski.
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
*/
Uwagi
W czasie kompilacji group klauzul zostały przetłumaczone na wywołania GroupBy``2 metody.
Zobacz też
Zadania
Porady: tworzenie grup zagnieżdżonych (Przewodnik programowania w języku C#)
Porady: grupowanie wyników kwerendy (Przewodnik programowania w języku C#)
Porady: wykonanie podzapytania w operacji grupowania (Przewodnik programowania w języku C#)
Informacje
Koncepcje
Wyrażenia kwerend LINQ (Przewodnik programowania w języku C#)