IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 9 - LINQ operátory 1

V předchozím kvízu, Kvíz - Slovníky, množiny, fronta, zásobník v C# .NET Kolekce, jsme si ověřili nabyté zkušenosti z předchozích lekcí.

Se základní syntaxí LINQ dotazů jsme již tedy obeznámeni. V několika lekcích si nyní popišme co vše nám LINQ nabízí, tedy metody, přesněji řečeno operátory, které můžete ve svých dotazech používat. Vše si ukážeme na příkladech. Prvních několik příkladů bude opakováním, s dalšími nabude práce s LINQ nových rozměrů.

Restrikční operátory

Výsledek dotazu můžeme nějak podmínit a vybrat tedy jen data, která splňují nějakou podmínku. Mezi restrikční operátory patří nám již známé where.

where

Operátor where umožňuje vybrat jen ta data, která splňují určitou podmínku. Z posloupnosti čísel vybereme tak, která jsou větší než 5:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = from c in cisla
            where (c > 5)
            select c;

foreach (int c in dotaz)
    Console.WriteLine(c);

Dotaz vybere:

Konzolová aplikace
8
9

Všechny další příklady budou obsahovat stejný kód pro výpis výsledku, v článku jej již znovu uvádět nebudeme.

Indexované Where()

Co jsme si ještě neukazovali je použití tzv. indexovaného Where(), ve kterém můžeme pracovat s indexem prvku v kolekci. Vyberme čísla, která mají stejnou hodnotu jako jejich index v poli:

int[] cisla = { 0, 5, 2, 5, 4, 1, 3, 7 };

var dotaz = cisla.Where((cislo, index) => cislo == index);

Dotaz vybere:

Konzolová aplikace
0
2
4
7

Použili jsme zde mimochodem zápis dotazu přes metody. Některé operátory jinak zapsat nelze a nepodporují SQL-like zápis, budeme se tu s nimi setkávat i nadále.

Projekční operátory

S vybranými prvky se nemusíme spokojit tak, jak jsou, ale můžeme z výsledných prvků vybrat pouze nějakou vlastnost.

select

Pomocí select určíme co konkrétně nás u vybraných prvků zajímá. Nechme si vrátit dvojnásobky čísel větších než 5:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = from c in cisla
            where (c > 5)
            select c * 2;

Dotaz vybere:

Konzolová aplikace
16
18

Stejně tak můžeme mapovat i nějakou vlastnost nebo výsledek metody, např. Length nebo ToLower() na řetězci:

string[] slova = { "SOcialNi", "SiT", "ITnetWOrk" };

var dotaz = from s in slova
            select s.ToLower();

Dotaz vybere:

Konzolová aplikace
socialni
sit
itnetwork

Indexovaný Select() s anonymními typy

Stejně jako Where() i u operátoru Select() máme přístup k indexu prvku. S anonymními typy jsme se seznámili v minulé lekci, ukažme si tedy, jak vybrat anonymní typ, obsahující pozici a hodnotu daného prvku:

int[] cisla = { 3, 5, 8, 5 };

var dotaz = cisla.Select((cislo, index) => new { Index = index, Hodnota = cislo });

Dotaz vybere:

Konzolová aplikace
{ Index = 0, Hodnota = 3 }
{ Index = 1, Hodnota = 5 }
{ Index = 2, Hodnota = 8 }
{ Index = 3, Hodnota = 5 }

Rozdělující operace

Původní kolekci můžeme nějakým způsobem rozdělit a dále pracovat pouze s její částí.

Take()

Take vybere prvních několik prvků z kolekce a zbytek zahodí. Vyberme si pouze první 3 čísla z pole:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = cisla.Take(3);

Dotaz vybere:

Konzolová aplikace
3
5
8

Take() s dotazem

Take() můžeme zavolat i na výsledku LINQ dotazu tak, že ho ozávorkujeme:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = (from c in cisla
             where (c > 3)
             select c * 2).Take(3);

Dotaz vybere:

Konzolová aplikace
10
16
10

Skip()

Skip() je opačná funkce k Take(), vybere tedy všechny prvky kromě několika prvních, které přeskočí, od toho název operátoru.

Vyberme z pole všechna čísla kromě 5 prvních:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = cisla.Skip(5);

Dotaz vybere:

Konzolová aplikace
1
3
4

Pomocí Skip() a Take() se často řeší výběr náhodného prvku:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };
Random r = new Random();

var dotaz = cisla.Skip(r.Next(cisla.Length)).Take(1);

Dotaz vybere 1 náhodné číslo z pole.

Při spuštění online se výsledek uloží do mezipaměti a bude to vypadat, že padá stále to samé číslo. Obnovení mezipaměti můžete provést změnou zdrojového kódu, např. přidáním nějakého komentáře.

TakeWhile()

Prvky můžeme vybírat postupně od začátku až do splnění určité podmínky. Od té chvíle přidávání prvků do výsledku ustane. Vyberme si prvních několik čísel, které jsou větší než 2:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = cisla.TakeWhile(c => c > 2);

Dotaz vybere:

Konzolová aplikace
3
5
8
5
9

TakeWhile() můžeme také indexovat.

SkipWhile()

Analogicky existuje i SkipWhile(), které by čísla přeskakovalo dokud platí určitá podmínka a až poté začne čísla do výsledku přidávat. Přeskočme prvních několik čísel, která jsou větší než 2:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = cisla.SkipWhile(c => c > 2);

Dotaz vybere:

Konzolová aplikace
1
3
4

SkipWhile() můžeme rovněž indexovat.

Skip() můžeme (jako každou podobnou metodu) zavolat jako u příkladu s Take() na dotazu tak, že ho ozávorkujeme. Toto již nebudu u dalších metod uvádět.

Řadicí operátory

S OrderBy(), OrderByDescending(), ThenBy() a ThenByDescending() jsme se již setkali. Ukažme si ale, jak můžeme řadit pomocí Compareru.

OrderBy() pomocí IComparer

Použití comparerů získává svou výhodu ve chvíli, kdy chceme dotaz parametrizovat a střídat kritéria podle kterých třídíme (necháme jejich výběr např. na uživateli). Nejprve je důležité deklarovat si svůj comparer, v ukázce použijeme comparer stringů, který porovnává stringy s ohledem na velká a malá písmena:

public class CaseSensitiveComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return string.Compare(x, y, StringComparison.Ordinal);
    }
}

Nyní comparer vložíme do dotazu:

string[] slova = { "Argentina", "anakonda", "aLbert", "Bizon", "brčál", "BOmba" };

var dotaz = slova.OrderBy(s => s, new CaseSensitiveComparer());
public class CaseSensitiveComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return string.Compare(x, y, StringComparison.Ordinal);
    }
}

Dotaz vybere:

Konzolová aplikace
Argentina
BOmba
Bizon
aLbert
anakonda
brčál

Množinové operátory

Na kolekci můžeme nahlížet jako na množinu a použít následující operátory, které nám často zjednoduší práci:

Distinct()

Distinct() vybere z kolekce pouze unikátní elementy. Vyberme tedy pouze unikátní čísla z pole:

int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 };

var dotaz = cisla.Distinct();

Dotaz vybere:

Konzolová aplikace
3
5
8
9
1
4

Union()

Union() vybere množinové sjednocení. Na vstupu jsou tedy 2 kolekce a na výstupu množina (kolekce) obsahující všechny prvky 2 vstupních kolekcí tak, že je každý obsažen pouze jednou. Zkusme si to:

int[] mnozina1 = { 3, 5, 8, 5, 9, 1, 3, 4 };
int[] mnozina2 = { 3, 7, 2, 1, 4 };

var dotaz = mnozina1.Union(mnozina2);

Dotaz vybere:

Konzolová aplikace
3
5
8
9
1
4
7
2

Intersect()

Intersect() vybere množinový průnik. Na vstupu jsou tedy 2 kolekce a na výstupu množina (kolekce) obsahující pouze prvky které jsou oběma vstupním kolekcím společné. Zkusme si to:

int[] mnozina1 = { 3, 5, 8, 5, 9, 1, 3, 4 };
int[] mnozina2 = { 3, 7, 2, 1, 4 };

var dotaz = mnozina1.Intersect(mnozina2);

Dotaz vybere:

Konzolová aplikace
3
1
4

Except()

Metoda Except() nám umožňuje vytvořit posloupnost obsahující ty hodnoty z první množiny, které se nevyskytují v množině druhé.

int[] mnozina1 = { 3, 5, 8, 5, 9, 1, 3, 4 };
int[] mnozina2 = { 3, 7, 2, 1, 4 };

var dotaz = mnozina1.Except(mnozina2);

Dotaz vybere:

Konzolová aplikace
5
8
9

V následujícím cvičení, Řešené úlohy k 7.-9. lekci práce s kolekcemi v C# .NET, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Kvíz - Slovníky, množiny, fronta, zásobník v C# .NET Kolekce
Všechny články v sekci
Kolekce a LINQ v C# .NET
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 7.-9. lekci práce s kolekcemi v C# .NET
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
260 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity