MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Filtrarea colecției

Pentru a selecta elemente dintr-un set pe baza unei condiții, se utilizează metoda Where:

Where<TSource> (Func<TSource,bool> predicate)

Această metodă primește un delegat Func<TSource,bool>, care acceptă fiecare element al secvenței ca parametru și returnează o valoare bool. Dacă elementul corespunde unei anumite condiții, se returnează true și atunci acel element este transmis în colecția returnată de metoda Where.

De exemplu, să selectăm toate șirurile a căror lungime este egală cu 3:

string[] people = { "Tom", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = people.Where(p => p.Length == 3); // "Tom", "Bob", "Sam", "Tim"

foreach (string person in selectedPeople)
   Console.WriteLine(person);

Dacă expresia din metoda Where pentru un anumit element este egală cu true (în acest caz expresia p.Length == 3), atunci acel element este inclus în selecția rezultată.

O interogare similară folosind operatorii LINQ:

string[] people = { "Tom", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = from p in people
                    where p.Length == 3
                    select p;

Un alt exemplu - să selectăm toate elementele pare care sunt mai mari de 10.

Filtrarea folosind operatorii LINQ:

int[] numbers = { 1, 2, 3, 4, 10, 34, 55, 66, 77, 88 };
// metode de extensie
var evens1 = numbers.Where(i => i % 2 == 0 && i > 10);
// operatori de interogare
var evens2 = from i in numbers
            where i % 2 == 0 && i > 10
            select i;

Selecția obiectelor complexe

Să presupunem că avem o clasă utilizator:

record class Person(string Name, int Age, List<string> Languages);

Proprietatea Name reprezintă numele, proprietatea Age - vârsta utilizatorului, iar lista Languages - lista de limbi pe care le cunoaște utilizatorul.

Să creăm un set de utilizatori și să selectăm dintre ei pe cei care au vârsta peste 25 de ani:

var people = new List<Person>
{
   new Person ("Tom", 23, new List<string> {"english", "german"}),
   new Person ("Bob", 27, new List<string> {"english", "french" }),
   new Person ("Sam", 29, new List<string>  { "english", "spanish" }),
   new Person ("Alice", 24, new List<string> {"spanish", "german" })
};

var selectedPeople = from p in people
                    where p.Age > 25
                    select p;

foreach (Person person in selectedPeople)
   Console.WriteLine($"{person.Name} - {person.Age}");

Afișarea pe consolă:

Bob - 27
Sam - 29

O interogare similară folosind metoda de extensie Where:

var selectedPeople = people.Where(p => p.Age > 25);

Filtre complexe

Acum să analizăm filtre mai complexe. De exemplu, în clasa utilizatorului există o listă de limbi pe care le cunoaște utilizatorul. Ce facem dacă trebuie să filtrăm utilizatorii după limba cunoscută:

var selectedPeople = from person in people
                    from lang in person.Languages
                    where person.Age < 28
                    where lang == "english"
                    select person;

Rezultat:

Tom - 23
Bob - 27

Pentru a crea o interogare similară folosind metodele de extensie, se aplică metoda SelectMany:

var selectedPeople = people.SelectMany(u => u.Languages,
                           (u, l) => new { Person = u, Lang = l })
                         .Where(u => u.Lang == "english" && u.Person.Age < 28)
                         .Select(u => u.Person);

Metoda SelectMany() primește ca prim parametru secvența care trebuie proiectată, iar ca al doilea parametru o funcție de transformare care se aplică fiecărui element. La ieșire, ea returnează 8 perechi "utilizator - limbă" (new { Person = u, Lang = l }), la care se aplică apoi filtrul folosind Where.

Filtrarea după tipul de date

O metodă de extensie suplimentară - OfType() - permite filtrarea datelor colecției după un anumit tip:

var people = new List<Person>
{
   new Student("Tom"),
   new Person("Sam"),
   new Student("Bob"),
   new Employee("Mike")
};

var students = people.OfType<Student>();

foreach (var student in students)
   Console.WriteLine(student.Name);

record class Person(string Name);
record class Student(string Name) : Person(Name);
record class Employee(string Name) : Person(Name);

În acest caz, lista people conține obiecte de trei tipuri - clasa Person și tipurile derivate Student și Employee. Și în exemplu se efectuează filtrarea datelor de tip Student - pentru aceasta, metoda OfType() este tipizată cu tipul Student. Afișarea pe consolă:

Tom
Bob
← Lecția anterioară Lecția următoare →