Mikuláš je tu! Získaj 90 % extra kreditov ZADARMO s promo kódom CERTIK90 pri nákupe od 1 199 kreditov. Len do nedele 7. 12. 2025! Zisti viac:
NOVINKA: Najžiadanejšie rekvalifikačné kurzy teraz s 50% zľavou + kurz AI ZADARMO. Nečakaj, táto ponuka dlho nevydrží! Zisti viac:

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 dopytov sme už 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átory, ktoré môžete vo svojich dopytoch používať. Všetko si ukážeme na príkladoch. Niekoľko prvých príkladov bude opakovaním, s ďalšími nadobudne práca s LINQ nové rozmery.

Reštrikčné operátory

Výsledok dopytu 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ámy 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);

Dopyt 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);

Dopyt vyberie:

Konzolová aplikácia
0
2
4
7

Použili sme tu mimochodom zápis dopytu 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;

Dopyt vráti:

Konzolová aplikácia
16
18

Rovnako 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();

Dopyt 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 });

Dopyt 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 niekoľko prvých prvkov z kolekcie a zvyšok zahodí. Vyberme si iba prvé tri čísla z poľa:

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

var query = numbers.Take(3);

Dopyt vyberie:

Konzolová aplikácia
3
5
8

Take() s dopyt

Take() môžeme zavolať aj na výsledku LINQ dopytu tak, že ho ozátvorkujeme:

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

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

Dopyt 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čí, od toho názov operátora.

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

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

var query = numbers.Skip(5);

Dopyt vyberie:

Konzolová aplikácia
1
3
4

Pomocou Skip() a Take() sa často rieši výber náhodného prvku:

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

var query = numbers.Skip(r.Next(numbers.Length)).Take(1);

Dopyt vyberie jedno 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 prestane. Vyberme si 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);

Dopyt 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 niekoľko prvých čísel, ktoré sú väčšie ako 2:

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

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

Dopyt 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 dopyte tak, že ho ozátvorkujeme. To už nebudem pri ďalších metódach 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 dopyt 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 textových reťazcov, ktorý porovnáva reťazce 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 dopytu:

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);
    }
}

Dopyt 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() odstráni duplicitné prvky a vráti jedinečné hodnoty v poradí, v ktorom sa prvýkrát objavili v pôvodnom poli:

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

var query = numbers.Distinct();

Dopyt vyberie:

Konzolová aplikácia
3
5
8
9
1
4

Union()

Union() vyberie množinové zjednotenie. Na vstupe sú teda dve kolekcie a na výstupe množina (kolekcia) obsahujúca všetky prvky dvoch 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);

Dopyt vyberie:

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

Intersect()

Intersect() vyberie množinový prienik. Na vstupe sú teda dve 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);

Dopyt 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);

Dopyt vyberie:

Konzolová aplikácia
5
8
9

V nasledujúcom cvičení, Riešené úlohy k 7.-9. lekcii 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
Kolekcie a LINQ v C# .NET
Preskočiť článok
(neodporúčame)
Riešené úlohy k 7.-9. lekcii práce s kolekciami v C# .NET
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
18 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