NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 11 - LINQ - Restrikční, Projekční operátory a Rozdělující operace

V předchozím kvízu, Kvíz - Slovníky, množiny, fronta, zásobník ve VB.NET Kolekce, jsme si ověřili nabyté zkušenosti z předchozích lekcí.

V dnešním LINQ tutoriálu pro VB.NET si popíšeme další operátory, které můžeme používat. Budou to operátory restrikční a projekční, a také rozdělující operace.

Restrikční operátory

Výsledek dotazu můžeme nějak podmínit a vybrat tedy jen data, která splňují nějakou podmínku. Mezi restrikční operátory patří nám již známé where.

where

Operátor where umožňuje vybrat jen ta data, která splňují určitou podmínku.

Z posloupnosti čísel vybereme tak, která jsou větší než 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

Dotaz vybere:

Konzolová aplikace
8
9

Indexované Where()

Co jsme si ještě neukazovali je použití tzv. indexovaného Where(), ve kterém můžeme pracovat s indexem prvku v kolekci. Vyberme čísla, která mají stejnou hodnotu jako jejich 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

Dotaz vybere:

Konzolová aplikace
0
2
4
7

Použili jsme zde zápis dotazu přes metody. Některé operátory jinak zapsat nelze a nepodporují SQL-like zápis. Budeme se tu s nimi setkávat i nadále.

Projekční operátory

S vybranými prvky se nemusíme spokojit tak, jak jsou, ale můžeme z výsledných prvků vybrat pouze nějakou vlastnost.

select

Pomocí select určíme co konkrétně nás u vybraných prvků zajímá. Nechme si vrátit dvojnásobky čísel větších než 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

Dotaz vybere:

Konzolová aplikace
16
18

Stejně tak můžeme mapovat i nějakou vlastnost nebo výsledek metody, např. Length nebo ToLower() na řetězci:

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

Dotaz vybere:

Konzolová aplikace
socialni
sit
itnetwork

Indexovaný Select() s anonymními typy

Stejně jako Where() i u operátoru Select() máme přístup k indexu prvku. S anonymními typy jsme se již seznámili.

Ukažme si tedy, jak vybrat anonymní typ, obsahující pozici 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

Dotaz vybere:

Konzolová aplikace
{ Index = 0, Hodnota = 3 }
{ Index = 1, Hodnota = 5 }
{ Index = 2, Hodnota = 8 }
{ Index = 3, Hodnota = 5 }

Rozdělující operace

Původní kolekci můžeme nějakým způsobem rozdělit a dále pracovat pouze s její částí.

Take()

Take() vybere prvních několik prvků z kolekce a zbytek zahodí. Vyberme si pouze první tři čísla z pole:

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

Dotaz vybere:

Konzolová aplikace
3
5
8

Take() s dotazem

Take() můžeme zavolat i 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

Dotaz vybere:

Konzolová aplikace
10
16
10

Skip()

Skip() je opačná funkce k Take(). Vybere tedy všechny prvky kromě několika prvních, které přeskočí.

Vyberme z pole všechna čísla kromě pěti první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

Dotaz vybere:

Konzolová aplikace
1
3
4

Pomocí Skip() a Take() se často řeší výběr 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

Dotaz vybere jedno náhodné číslo z pole.

TakeWhile()

Prvky můžeme vybírat postupně od začátku až do splnění určité podmínky. Od té chvíle se přidávání prvků do výsledku zastaví.

Vyberme si prvních několik čísel, které jsou větší než 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

Dotaz vybere:

Konzolová aplikace
3
5
8
5
9

TakeWhile() můžeme také indexovat.

SkipWhile()

Analogicky existuje i SkipWhile(), které by čísla přeskakovalo dokud platí určitá podmínka a až poté začne čísla do výsledku přidávat.

Přeskočme prvních několik čísel, která jsou větší než 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

Dotaz vybere:

Konzolová aplikace
1
3
4

SkipWhile() můžeme rovněž indexovat.

Skip() můžeme (jako každou podobnou metodu) zavolat jako u příkladu s Take() na dotazu tak, že ho ozávorkujeme. Toto již nebudu u dalších metod uvádět.

V příští lekci, LINQ - Řadicí a Množinové operátory ve VB.NET, budeme pokračovat v popisu syntaxe LINQ operátorů. Budou to operátory řadicí a množinové.


 

Předchozí článek
Kvíz - Slovníky, množiny, fronta, zásobník ve VB.NET Kolekce
Všechny články v sekci
Kolekce a LINQ ve VB.NET
Přeskočit článek
(nedoporučujeme)
LINQ - Řadicí a Množinové operátory ve VB.NET
Článek pro vás napsal Přemysl Šíma
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
APSima
Aktivity