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í.

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 :)


 

Predchádzajúci článok
LINQ provideri, anonymné typy, radenie a zoskupovanie
Všetky články v sekcii
Kolekcia v C # .NET a LINQ
Preskočiť článok
(neodporúčame)
LINQ operátormi 2
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
1 hlasov
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 sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity