This article has been localized into Czech by the community.
Filtrování dat: Metoda Where()
V jednom z nejzákladnějších (ale také nejmocnějších) operací, které můžete provést na sadě dat, je filtrování některých z nich. Již jsme viděli náhled toho, co můžete dělat s metodou Where() v úvodním článku o LINQ, ale v tomto článku se ponoříme trochu hlouběji. Již jsme diskutovali o tom, jak mnoho metod LINQ může používat lambda výrazy k provedení svého úkolu a metoda Where() je jednou z nich - poskytne každou položku jako vstup a poté vy poskytnete logiku, která rozhodne, zda je položka zahrnuta (vrátí true) nebo vyloučena (vrátí false) z konečného výsledku. Zde je základní příklad:
List<int> numbers = new List<int>()
{
1, 2, 4, 8, 16, 32
};
var smallNumbers = numbers.Where(n => n < 10);
foreach (var n in smallNumbers)
Console.WriteLine(n);
V tomto příkladu je každé číslo kontrolováno proti našemu výrazu, který vrátí true, pokud je číslo menší než 10, a false, pokud je 10 nebo vyšší. Výsledkem je verze původního seznamu, kde jsou zahrnuta pouze čísla menší než 10, která jsou poté vypsána na konzoli.
Ale výraz nemusí být tak jednoduchý - můžeme do něj snadno přidat další požadavky, stejně jako by to byl obyčejný if-příkaz:
List<int> numbers = new List<int>()
{
1, 2, 4, 8, 16, 32
};
var smallNumbers = numbers.Where(n => n > 1 && n != 4 && n < 10);
foreach (var n in smallNumbers)
Console.WriteLine(n);
Určujeme, že číslo musí být větší než 1, ale nesmí být konkrétně číslo 4, a musí být menší než 10.
Samozřejmě můžete ve svém výrazu použít i různá volání metod - pokud je konečným výsledkem boolean hodnota, aby metoda Where() věděla, zda chcete položku zahrnout nebo ne, jste na správné cestě. Zde je příklad:
List<int> numbers = new List<int>()
{
1, 2, 4, 7, 8, 16, 29, 32, 64, 128
};
List<int> excludedNumbers = new List<int>()
{
7, 29
};
var validNumbers = numbers.Where(n => !excludedNumbers.Contains(n));
foreach (var n in validNumbers)
Console.WriteLine(n);
V tomto příkladu deklarujeme druhý seznam čísel - jakousi černou listinu čísel, která nechceme zahrnout! V metodě Where() používáme metodu Contains() na černé listině, abychom rozhodli, zda může být číslo zahrnuto do konečného seznamu čísel nebo ne.
A samozřejmě to funguje i pro složitější objekty než čísla a řetězce, a stále je to velmi snadné na použití. Podívejte se na tento příklad, kde používáme objekty s informacemi o uživatelích místo čísel a používáme metodu Where() k získání seznamu uživatelů se jmény začínajícími na písmeno "J", ve věku 39 let nebo méně:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqWhere2
{
class Program
{
static void Main(string[] args)
{
List<User> listOfUsers = new List<User>()
{
new User() { Name = "John Doe", Age = 42 },
new User() { Name = "Jane Doe", Age = 34 },
new User() { Name = "Joe Doe", Age = 8 },
new User() { Name = "Another Doe", Age = 15 },
};
var filteredUsers = listOfUsers.Where(user => user.Name.StartsWith("J") && user.Age < 40);
foreach (User user in filteredUsers)
Console.WriteLine(user.Name + ": " + user.Age);
}
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
}
}
A pro srovnání, zde je, jak by operace where vypadala, pokud bychom místo metody použili syntaxi dotazu:
// Method syntax
var filteredUsers = listOfUsers.Where(user => user.Name.StartsWith("J") && user.Age < 40);
// Query syntax
var filteredUsersQ = from user in listOfUsers where user.Name.StartsWith("J") && user.Age < 40 select user;
Řetězení více metod Where()
O tomto jsme se stručně zmínili v úvodu k LINQ: Skutečný výsledek výrazu LINQ není realizován, dokud data skutečně nepotřebujete, například když je procházíte ve smyčce, počítáte je nebo nad nimi iterujete (jak to děláme v našich příkladech). To také znamená, že můžete řetězit více metod Where() dohromady, pokud se vám to zdá snazší číst - u velmi složitých výrazů to rozhodně může být! Zde je upravená verze našeho předchozího příkladu:
List<int> numbers = new List<int>()
{
1, 2, 4, 8, 16, 32
};
var smallNumbers = numbers.Where(n => n > 1).Where(n => n != 4).Where(n => n < 10);
foreach (var n in smallNumbers)
Console.WriteLine(n);
Výsledek je přesně stejný a i když první verze nemusela být dostatečně složitá na to, aby odůvodnila rozdělení do více volání metod Where(), pravděpodobně narazíte na situace, kdy to dává dobrý smysl. Chci zdůraznit, že to nepřináší extra náklady z hlediska výkonu, protože skutečná operace (operace) "where" není provedena až do chvíle, kdy procházíme výsledkem - do té doby kompilátor a interpretátor optimalizují váš dotaz, aby byl co nejrychlejší, bez ohledu na to, jak jste ho napsali.
Shrnutí
Pomocí metody Where() můžete snadno odfiltrovat nechtěné položky ze zdroje dat a vytvořit podmnožinu původních dat. Pamatujte, že skutečně dostáváte novou sadu dat - původní zdroj dat zůstane nedotčen, pokud konkrétně nepřepíšete původní proměnnou.