9. diel - LINQ operátormi 1
V minulej lekcii, LINQ provideri, anonymné typy, radenie a zoskupovanie , sme sa v LINQ naučili anonymné typy a ukázali si základy radenie a zoskupovanie.
So základnou syntaxou LINQ dotazov sme už teda oboznámení. V niekoľkých lekciách si teraz popíšme čo všetko nám LINQ ponúka, teda metódy, presnejšie povedané operátormi, ktoré môžete vo svojich otázkach používať. Všetko si ukážeme na príkladoch. Prvých niekoľko príkladov bude opakovaním, s ďalšími nadobudne práce s LINQ nových rozmerov.
Reštrikčné operátormi
Výsledok dotazu môžeme nejako podmieniť a vybrať teda len údaje, ktoré
spĺňajú nejakú podmienku. Medzi restrikčné operátormi patrí nám už
známe where
.
Where
Operátor where
umožňuje vybrať len tie dáta, ktoré
spĺňajú určitú podmienku. Z postupnosti čísiel vyberieme tak, ktoré sú
väčšie ako 5
:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = from c in cisla where (c > 5) select c;
Otázka vyberie:
8 9
Indexované where
Čo sme si ešte neukazovali je použitie tzv. Indexovaného
where
, v ktorom môžeme pracovať s indexom prvku v kolekcii.
Vyberme čísla, ktoré majú rovnakú hodnotu ako ich index v poli:
int[] cisla = { 0, 5, 2, 5, 4, 1, 3, 7 }; var dotaz = cisla.Where((cislo, index) => cislo == index);
Otázka vyberie:
0 2 4 7
Použili sme tu mimochodom zápis dotazu cez metódy. Niektoré operátory inak nie je možné zapísať a nepodporujú SQL-like zápis, budeme sa tu s nimi stretávať aj naďalej.
Projekčné operátormi
S vybranými prvky sa nemusíme uspokojiť tak, ako sú, ale môžeme z výsledných prvkov vybrať iba nejakú vlastnosť.
Select
Pomocou select
určíme čo konkrétne nás pri vybraných
prvkov zaujíma. Nechajme si vrátiť dvoujnásobky čísel väčších ako
5
:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = from c in cisla where (c > 5) select c * 2;
Otázka vyberie:
16 18
Rovnako tak môžeme mapovať aj nejakú vlastnosť alebo výsledok metódy,
napr. Length
alebo ToLower()
na reťazci:
string[] slova = { "SOcialNi", "SiT", "ITnetWOrk" }; var dotaz = from s in slova select s.ToLower();
Otázka vyberie:
socialni sit itnetwork
Indexovaný select s anonymnými typmi
Rovnako ako where
iu operátoru select
máme
prístup k indexu prvku. S anonymnými typy sme sa zoznámili v minulej lekcii,
ukážme si teda, ako vybrať anonymný typ, obsahujúci pozíciu a hodnotu
daného prvku:
int[] cisla = { 3, 5, 8, 5 }; var dotaz = cisla.Select((cislo, index) => new { Index = index, Hodnota = cislo });
Otázka vyberie:
{ Index = 0, Hodnota = 3 } { Index = 1, Hodnota = 5 } { Index = 2, Hodnota = 8 } { Index = 3, Hodnota = 5 }
Rozdeľujúce operácie
Pôvodný kolekcii môžeme nejakým spôsobom rozdeliť a ďalej pracovať iba s jej časťou.
Take
Take vyberie prvých niekoľko prvkov z kolekcie a zvyšok zahodí. Vyberme si iba prvý 3 čísla z poľa:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = cisla.Take(3);
Otázka vyberie:
3 5 8
Take s dotazom
Take môžeme zavolať aj 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);
Otázka vyberie:
10 16 10
Skip
Skip()
je opačná funkcia k Take()
, vyberie teda
všetky prvky okrem niekoľkých prvých, ktoré preskočí, od toho názov
operátora.
Vyberme z poľa všetky čísla okrem 5tich prvých:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = cisla.Skip(5);
Otázka vyberie:
1 3 4
Pomocou Skip()
a Take()
sa často riešia výber
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);
Otázka vyberie 1 náhodné číslo z poľa.
TakeWhile
Prvky môžeme vyberať postupne od začiatku až do splnenia určité podmienky. Od tej chvíle pridávanie prvkov do výsledku ustane. Vyberme si prvých niekoľko čísel, ktoré sú väčšie ako 2:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = cisla.TakeWhile(c => c > 2);
Otázka vyberie:
3 5 8 5 9
TakeWhile()
môžeme tiež indexovať.
SkipWhile
Analogicky existuje i SkipWhile()
, ktoré by čísla preskakoval
kým platia určité podmienka a až potom začne čísla do výsledku
pridávať. Preskočme prvých niekoľko čísel, ktoré sú väčšie ako
2
:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = cisla.SkipWhile(c => c > 2);
Otázka vyberie:
1 3 4
SkipWhile()
môžeme tiež indexovať.
Skip()
môžeme (ako každú podobnú metódu) zavolať ako u
príkladu s Take()
na dotaze tak, že ho ozávorkujeme. Toto už
nebudem u ďalších metód uvádzať.
Radiacej operátormi
S OrderBy()
, OrderByDescending()
,
ThenBy()
a ThenByDescending()
sme sa už stretli.
Ukážme si ale, ako môžeme radiť pomocou Comparer.
Orderby pomocou Comparer
Použitie Comparer získava svoju výhodu vo chvíli, keď chceme dotaz parametrizovať a striedať kritériá podľa ktorých triedime (necháme ich výber napr. Na užívateľovi). Najprv je dôležité deklarovať si svoj Comparer, v ukážke použijeme Comparer stringov, ktorý porovnáva stringy s ohľadom na veľké a malé písmená:
public class CaseSensitiveComparer : IComparer<string> { public int Compare(string x, string y) { return string.Compare(x, y, StringComparison.Ordinal); } }
Teraz Comparer vložíme do dotazu:
string[] slova = { "Argentina", "anakonda", "aLbert", "Bizon", "brčál", "BOmba" }; var dotaz = slova.OrderBy(s => s, new CaseSensitiveComparer());
Otázka vyberie:
Argentina BOmba Bizon aLbert anakonda brčál
Množinové operátormi
Na kolekcii môžeme pozerať ako na množinu a použiť nasledujúce operátory, ktoré nám často zjednodušia prácu:
Distinct
Distinct()
vyberie z kolekcie iba unikátne elementy. Vyberme
teda iba unikátne čísla z poľa:
int[] cisla = { 3, 5, 8, 5, 9, 1, 3, 4 }; var dotaz = cisla.Distinct();
Otázka vyberie:
3 5 8 9 1 4
Union
Union()
vyberie množinové zjednotenie. Na vstupe sú teda 2
kolekcie a na výstupe množina (kolekcia) obsahujúci všetky prvky 2
vstupných kolekcií tak, že je každý obsiahnutý len raz. Skúsme si to:
int[] mnozina1 = { 3, 5, 8, 5, 9, 1, 3, 4 }; int[] mnozina2 = { 3, 7, 2, 1, 4 }; var dotaz = mnozina1.Union(mnozina2);
Otázka vyberie:
3 5 8 9 1 4 7 2
INTERSECT
Intersect()
vyberie Množinový prienikom. Na vstupe sú teda 2
kolekcie a na výstupe množina (kolekcia) obsahujúci iba prvky ktoré sú obom
vstupným kolekciám spoločné. Skúsme si to:
int[] mnozina1 = { 3, 5, 8, 5, 9, 1, 3, 4 }; int[] mnozina2 = { 3, 7, 2, 1, 4 }; var dotaz = mnozina1.Intersect(mnozina2);
Otázka vyberie:
3 1 4
Except
Metóda Except()
nám umožňuje vytvoriť postupnosť
obsahujúci tie hodnoty z prvej množiny, ktoré sa nevyskytujú v množine
druhej.
int[] mnozina1 = { 3, 5, 8, 5, 9, 1, 3, 4 }; int[] mnozina2 = { 3, 7, 2, 1, 4 }; var dotaz = mnozina1.Except(mnozina2);
Otázka vyberie:
5 8 9
V budúcej lekcii, LINQ operátormi 2 , budeme pokračovať v opise operátorov LINQ, uvidíte, že toho vie ešte veľa