Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.
IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

9. diel - LINQ operátory 1

V predchádzajúcom kvíze, Kvíz - Slovníky, množiny, front, zásobník v C# .NET Kolekcia, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.

So základnou syntaxou LINQ otázok 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áca s LINQ nových rozmerov.

Reštrikčné operátory

Výsledok dotazu môžeme nejako podmieniť a vybrať teda len dáta, ktoré spĺňajú nejakú podmienku. Medzi reštrikčné operátory 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 čísel vyberieme tak, ktoré sú väčšie ako 5:

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

var query = from n in numbers
            where (n > 5)
            select n;

foreach (int number in query)
    Console.WriteLine(number);

Otázka vyberie:

Konzolová aplikácia
8
9

Všetky ďalšie príklady budú obsahovať rovnaký kód pre výpis výsledku, v článku ho už znova uvádzať nebudeme.

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[] numbers = { 0, 5, 2, 5, 4, 1, 3, 7 };

var query = numbers.Where((number, index) => number == index);

Otázka vyberie:

Konzolová aplikácia
0
2
4
7

Použili sme tu mimochodom zápis dotazu cez metódy. Niektoré operátory inak zapísať nemožno a nepodporujú SQL-like zápis, budeme sa tu s nimi stretávať aj naďalej.

Projekčné operátory

S vybranými prvkami 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 prvkoch zaujíma. Nechajme si vrátiť dvojnásobky čísel väčších ako 5:

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

var query = from n in numbers
            where (n > 5)
            select n * 2;

Otázka vyberie:

Konzolová aplikácia
16
18

Rovnako tak môžeme mapovať aj nejakú vlastnosť alebo výsledok metódy, napr. Length alebo ToLower() na reťazci:

string[] words = { "SOcial", "nEtwork", "ICTdemy" };

var query = from w in words
            select w.ToLower();

Otázka vyberie:

Konzolová aplikácia
social
network
ictdemy

Indexovaný Select() s anonymnými typmi

Rovnako ako Where() aj u operátora Select() máme prístup k indexu prvku. S anonymnými typmi 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[] numbers = { 3, 5, 8, 5 };

var query = numbers.Select((number, index) => new { Index = index, Value = number });

Otázka vyberie:

Konzolová aplikácia
{ Index = 0, Value = 3 }
{ Index = 1, Value = 5 }
{ Index = 2, Value = 8 }
{ Index = 3, Value = 5 }

Rozdeľujúce operácie

Pôvodnú kolekciu 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[] numbers = { 3, 5, 8, 5, 9, 1, 3, 4 };

var query = numbers.Take(3);

Otázka vyberie:

Konzolová aplikácia
3
5
8

Take() s dotazom

Take() môžeme zavolať aj na výsledku LINQ dotazu tak, že ho ozátvoríme:

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

var query = (from n in numbers
             where (n > 3)
             select n * 2).Take(3);

Otázka vyberie:

Konzolová aplikácia
10
16
10

Skip()

Skip() je opačná funkcia k Take(), vyberie teda všetky prvky okrem niekoľkých prvých, ktoré preskočia, od toho názov operátora.

Vyberme z poľa všetky čísla okrem 5 prvých:

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

var query = numbers.Skip(5);

Otázka vyberie:

Konzolová aplikácia
1
3
4

Pomocou Skip() a Take() sa často rieši 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.

Pri spustení online sa výsledok uloží do medzipamäte a bude to vyzerať, že padá stále to isté číslo. Obnovenie vyrovnávacej pamäte môžete vykonať zmenou zdrojového kódu, napr. pridaním nejakého komentára.

TakeWhile()

Prvky môžeme vyberať postupne od začiatku až do splnenia určitej 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[] numbers = { 3, 5, 8, 5, 9, 1, 3, 4 };

var query = numbers.TakeWhile(n => n > 2);

Otázka vyberie:

Konzolová aplikácia
3
5
8
5
9

TakeWhile() môžeme tiež indexovať.

SkipWhile()

Analogicky existuje aj SkipWhile(), ktoré by čísla preskakovalo pokiaľ platí 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[] numbers = { 3, 5, 8, 5, 9, 1, 3, 4 };

var query = numbers.SkipWhile(n => n > 2);

Otázka vyberie:

Konzolová aplikácia
1
3
4

SkipWhile() môžeme tiež indexovať.

Skip() môžeme (ako každú podobnú metódu) zavolať ako pri príklade s Take() na dotaze tak, že ho ozátvoríme. Toto už nebudem u ďalších metód uvádzať.

Radiace operátory

S OrderBy(), OrderByDescending(), ThenBy() a ThenByDescending() sme sa už stretli. Ukážme si ale, ako môžeme radiť pomocou Comparera.

OrderBy() pomocou IComparer

Použitie comparerov 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 otázky:

string[] words = { "Argentina", "anaconda", "aLbert", "Buffalo", "business", "BOmb" };

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

Otázka vyberie:

Konzolová aplikácia
Argentina
BOmb
Buffalo
aLbert
anaconda
business

Množinové operátory

Na kolekciu 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[] numbers = { 3, 5, 8, 5, 9, 1, 3, 4 };

var query = numbers.Distinct();

Otázka vyberie:

Konzolová aplikácia
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úca všetky prvky 2 vstupných kolekcií tak, že je každý obsiahnutý iba raz. Skúsme si to:

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

var query = set1.Union(set2);

Otázka vyberie:

Konzolová aplikácia
3
5
8
9
1
4
7
2

Intersect()

Intersect() vyberie množinový prienik. Na vstupe sú teda 2 kolekcie a na výstupe množina (kolekcia) obsahujúca iba prvky ktoré sú obom vstupným kolekciám spoločné. Skúsme si to:

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

var query = set1.Intersect(set2);

Otázka vyberie:

Konzolová aplikácia
3
1
4

Except()

Metóda Except() nám umožňuje vytvoriť postupnosť obsahujúcu tie hodnoty z prvej množiny, ktoré sa nevyskytujú v množine druhej.

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

var query = set1.Except(set2);

Otázka vyberie:

Konzolová aplikácia
5
8
9

V nasledujúcom cvičení, Riešené úlohy k 7.-9. lekciu práce s kolekciami v C# .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Predchádzajúci článok
Kvíz - Slovníky, množiny, front, zásobník v C# .NET Kolekcia
Všetky články v sekcii
Kolekcia a LINQ v C# .NET
Preskočiť článok
(neodporúčame)
Riešené úlohy k 7.-9. lekciu práce s kolekciami v C# .NET
Č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