OrderBy i grupowanie
Sortowanie i grupowanie wyników
OrderBy i grupowanie to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Sortowanie za pomocą OrderBy
OrderBy sortuje sekwencję rosnąco według wybranego klucza. Lambda zwraca wartość, według której odbywa się sortowanie.
Operator zwraca nową posortowaną sekwencję i jest stabilny, co oznacza, że elementy o równych kluczach zachowują swoją pierwotną kolejność względem siebie.
using System;
using System.Linq;
int[] nums = { 4, 1, 3, 2 };
var sorted = nums.OrderBy(n => n);
Console.WriteLine(string.Join(", ", sorted));Kolejność malejąca
OrderByDescending sortuje według wybranego klucza od największej wartości do najmniejszej.
Należy użyć go bezpośrednio zamiast sortować rosnąco i odwracać wynik — jasno wyraża intencję i sortuje w jednym przebiegu.
using System;
using System.Linq;
int[] scores = { 70, 95, 60, 88 };
var ranked = scores.OrderByDescending(s => s);
Console.WriteLine(string.Join(", ", ranked));Sortowanie według właściwości
W przypadku obiektów należy wybrać właściwość, według której ma odbywać się sortowanie. OrderBy(p => p.Age) sortuje osoby od najmłodszej do najstarszej.
Kluczem może być dowolny typ porównywalny — liczby, ciągi znaków, daty — lub dowolny typ implementujący IComparable.
using System;
using System.Linq;
using System.Collections.Generic;
record P(string Name, int Age);
var people = new List<P> { new("Ana", 30), new("Bo", 22) };
var byAge = people.OrderBy(p => p.Age);
foreach (var p in byAge) Console.WriteLine(p.Name);Sortowanie drugorzędne za pomocą ThenBy
ThenBy dodaje kryterium rozstrzygające. Po użyciu OrderBy sortuje elementy mające ten sam klucz główny według drugiego klucza.
Można łączyć kilka wywołań ThenBy/ThenByDescending, aby uzyskać sortowanie wielopoziomowe.
using System;
using System.Linq;
using System.Collections.Generic;
record P(string Name, int Age);
var people = new List<P> { new("Bo", 30), new("Ana", 30), new("Cy", 22) };
var ordered = people.OrderBy(p => p.Age).ThenBy(p => p.Name);
foreach (var p in ordered) Console.WriteLine($"{p.Age} {p.Name}");Dlaczego nie używać drugiego OrderBy
Dwukrotne wywołanie OrderBy nie zapewnia kryterium rozstrzygającego — drugie wywołanie sortuje wszystko ponownie i usuwa efekt pierwszego sortowania.
W przypadku sortowania warstwowego po początkowym OrderBy należy zawsze używać ThenBy.
using System;
using System.Linq;
using System.Collections.Generic;
record P(string N, int A);
var ps = new List<P> { new("Bo", 30), new("Ana", 30) };
var wrong = ps.OrderBy(p => p.A).OrderBy(p => p.N);
foreach (var p in wrong) Console.WriteLine(p.N);Klauzula orderby w składni zapytań
Składnia zapytań udostępnia klauzulę orderby. Można podać wiele kluczy oddzielonych przecinkami, opcjonalnie dodając descending.
orderby p.Age, p.Name descending sortuje według wieku, a w przypadku remisu — według imienia w odwrotnej kolejności.
using System;
using System.Linq;
using System.Collections.Generic;
record P(string N, int A);
var ps = new List<P> { new("Bo", 30), new("Ana", 30), new("Cy", 22) };
var q = from p in ps orderby p.A, p.N select p.N;
Console.WriteLine(string.Join(", ", q));Grupowanie za pomocą GroupBy
GroupBy dzieli sekwencję na grupy elementów mających wspólny klucz. Zwraca sekwencję obiektów IGrouping<TKey, TElement>.
Każda grupa udostępnia właściwość Key i sama jest iterowalna, zwracając elementy należące do tej grupy.
using System;
using System.Linq;
int[] nums = { 1, 2, 3, 4, 5, 6 };
var groups = nums.GroupBy(n => n % 2 == 0 ? "even" : "odd");
foreach (var g in groups)
Console.WriteLine($"{g.Key}: {string.Join(\",\", g)}");Klucz grupy i jej elementy
Właściwość Key każdej grupy identyfikuje daną partycję, a iterowanie po grupie zwraca jej elementy. Można bezpośrednio wywołać na grupie metodę Count().
W ten sposób można tworzyć histogramy, zestawienia liczności i podziały na kategorie.
using System;
using System.Linq;
string[] fruit = { "apple", "avocado", "banana", "cherry" };
var byLetter = fruit.GroupBy(f => f[0]);
foreach (var g in byLetter)
Console.WriteLine($"{g.Key}: {g.Count()}");Grupowanie, a następnie projekcja
Popularny wzorzec polega na przekształceniu każdej grupy w obiekt podsumowania za pomocą Select użytego po GroupBy.
Odczytuje się właściwość Key i agreguje elementy, na przykład obliczając liczbę lub sumę dla każdej grupy.
using System;
using System.Linq;
using System.Collections.Generic;
record Sale(string City, int Amt);
var sales = new List<Sale> { new("NY", 5), new("LA", 3), new("NY", 2) };
var totals = sales.GroupBy(s => s.City)
.Select(g => new { g.Key, Sum = g.Sum(x => x.Amt) });
foreach (var t in totals) Console.WriteLine($"{t.Key}={t.Sum}");GroupBy z selektorem elementów
GroupBy ma przeciążenie przyjmujące drugą lambdę — selektor elementów — który określa, jakie dane będą przechowywane w każdej grupie, a nie tylko sposób wyznaczania jej klucza.
W tym przypadku grupujemy według miasta, ale przechowujemy wyłącznie kwoty.
using System;
using System.Linq;
using System.Collections.Generic;
record Sale(string City, int Amt);
var sales = new List<Sale> { new("NY", 5), new("NY", 2) };
var g = sales.GroupBy(s => s.City, s => s.Amt);
foreach (var grp in g)
Console.WriteLine($"{grp.Key}: {string.Join(\",\", grp)}");Sortowanie i grupowanie są odroczone
Zarówno OrderBy, jak i GroupBy korzystają z odroczonego wykonania — są wykonywane podczas wyliczania elementów. Należy jednak pamiętać, że sortowanie i grupowanie muszą odczytać całe źródło, aby zwrócić pierwszy element.
W przeciwieństwie do Where nie działają więc strumieniowo; cały koszt pojawia się podczas pierwszej iteracji.
using System;
using System.Linq;
int[] nums = { 3, 1, 2 };
var q = nums.OrderBy(n => n);
Console.WriteLine("Query built");
Console.WriteLine(string.Join(", ", q));Szybkie sprawdzenie
Zastanówmy się nad sortowaniem wielopoziomowym.
Podsumowanie
OrderBy/OrderByDescending sortują według klucza, a ThenBy dodaje kryteria rozstrzygające. Drugie OrderBy sortuje dane ponownie i nie pełni funkcji kryterium rozstrzygającego.
GroupBy dzieli dane na obiekty IGrouping zawierające właściwość Key i elementy grupy, które często są następnie przekształcane w podsumowania. Obie operacje są odroczone, ale odczytują całe źródło. Następnie zajmiemy się agregowaniem i materializacją.
Często zadawane pytania
Czy lekcja „OrderBy i grupowanie” jest bezpłatna?
Tak — pełny tekst „OrderBy i grupowanie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „OrderBy i grupowanie”?
Sortowanie i grupowanie wyników Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „OrderBy i grupowanie”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Where i filtrowanie
- Select i projekcja
- OrderBy i grupowanie
- Agregaty i ToList