11. diel - LINQ - Reštrikčné, Projekčné operátory a Rozdeľujúce operácie
V minulej lekcii, LINQ vo VB.NET - Provideri, radenie a zoskupovanie , sme si popísali LINQ providerov a začali s popisom syntaxe LINQ pre radenie a zoskupovanie.
V dnešnom LINQ tutoriále pre VB.NET si popíšeme ďalších operátorov, ktorých môžeme používať. Budú to operátormi reštrikčné a projekčné, a tiež rozdeľujúce operácie.
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ámewhere
.
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
:
Dim cisla1 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz1 = From c In cisla1 Where (c > 5) Select c For Each c As Integer In dotaz1 Console.WriteLine(c) Next
Otázka vyberie:
Konzolová aplikácia
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:
Dim cisla2 As Integer() = {0, 5, 2, 5, 4, 1, 3, 7} Dim dotaz2 As Object = cisla2.Where(Function(cislo, index) cislo = index) For Each c As Integer In dotaz2 Console.WriteLine(c) Next
Otázka vyberie:
Konzolová aplikácia
0
2
4
7
Použili sme tu zápisnicu 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
:
Dim cisla3 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz3 As Object = From c In cisla3 Where (c > 5) Select c * 2 For Each c As Integer In dotaz3 Console.WriteLine(c) Next
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:
Dim slova As String() = {"SOcialNi", "SiT", "ITnetWOrk"} Dim dotaz = From s In slova Select s.ToLower() For Each s As String In dotaz Console.WriteLine(s) Next
Otázka vyberie:
Konzolová aplikácia
socialni
sit
itnetwork
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 už zoznámili.
Ukážme si teda, ako vybrať anonymný typ, obsahujúci pozíciu a hodnotu daného prvku:
Dim cisla5 As Integer() = {3, 5, 8, 5} Dim dotaz5 = cisla5.[Select](Function(cislo, index) New With {.Index = index, .Hodnota = cislo}) For Each d As Object In dotaz5 Console.WriteLine(d) Next
Otázka vyberie:
Konzolová aplikácia
{ Index = 0, Hodnota = 3 }
{ Index = 1, Hodnota = 5 }
{ Index = 2, Hodnota = 8 }
{ Index = 3, Hodnota = 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é tri čísla z
poľa:
Dim cisla6 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz6 = cisla6.Take(3) For Each d As Object In dotaz6 Console.WriteLine(d) Next
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ávorkujeme:
Dim cisla7 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz7 = (From c In cisla7 Where c > 3 Select c * 2).Take(3) For Each d As Object In dotaz7 Console.WriteLine(d) Next
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.
Vyberme z poľa všetky čísla okrem piatich prvých:
Dim cisla8 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz8 = cisla8.Skip(5) For Each d As Object In dotaz8 Console.WriteLine(d) Next
Otázka vyberie:
Konzolová aplikácia
1
3
4
Pomocou Skip()
a Take()
sa často rieši výber
náhodného prvku:
Dim cisla9 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim r As New Random(Now.Millisecond) ' inicializace random s "náhodnou" hodnotou ' pokud neuvedeme, pak dotaz bude vracet stejný prvek Dim dotaz9 As Object = cisla9.Skip(r.[Next](cisla9.Length)).Take(1) For Each d As Integer In dotaz9 Console.WriteLine(d) Next
Otázka vyberie jedno náhodné číslo z poľa.
TakeWhile()
Prvky môžeme vyberať postupne od začiatku až do splnenia
určitej podmienky. Od tej chvíle sa pridávanie prvkov do
výsledku zastaví.
Vyberme si prvých niekoľko čísel, ktoré sú väčšie
ako 2
:
Dim cisla10 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz10 = cisla10.TakeWhile(Function(c) c > 2) For Each d As Integer In dotaz10 Console.WriteLine(d) Next
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
:
Dim cisla11 As Integer() = {3, 5, 8, 5, 9, 1, 3, 4} Dim dotaz11 = cisla11.SkipWhile(Function(c) c > 2) For Each d As Integer In dotaz11 Console.WriteLine(d) Next
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ávorkujeme. Toto už nebudem u ďalších metód uvádzať.
V budúcej lekcii, LINQ - Radiaci a Množinové operátory , budeme pokračovať v popise syntaxe LINQ operátorov. Budú to operátory radiace a množinové.