This article has been localized into Dutch by the community.
Het filteren van data: de Where() method
Een van de meest basale (maar ook de meest krachtige) operaties die je kunt loslaten op een reeks data is die waarmee je enkele gegevens uit die reeks kan filteren. We zagen al een glimp van wat je kunt doen met de Where() method in het inleidende artikel over LINQ, maar in dit artikel graven we een beetje dieper. We hebben al besproken hoeveel LINQ methods een Lambda Expressie kunnen gebruiken om zijn werk te doen en de Where() method is er één van. Hij maakt van elk item de input en vervolgens kan jij de logica leveren die gaat bepalen of het item wordt toegevoegd (geretourneerd als true) of wordt buitengesloten (geretourneerd als false) uit het uiteindelijke resultaat. Hier is een basaal voorbeeld:
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);
In dit voorbeeld wordt elk getal gecheckt tegen onze expressie, die true zal retourneren als het getal kleiner is dan 10 en false als het 10 is of hoger. Als resultaat krijgen we een versie van de oorspronkelijke lijst, waar alleen getallen van onder de 10 staan, wat dan naar de console wordt gestuurd.
Maar de expressie hoeft niet zó simpel te zijn. We kunnen er gemakkelijk meer vereisten aan toevoegen, net alsof het een regulier statement was:
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);
We specificeren dat het getal groter moet zijn dan 1, maar dan niet het specifieke getal 4, en kleiner dan 10.
We kunnen natuurlijk ook allerlei methods aanroepen gebruiken in onze expressie, zolang het eindresultaat een boolean waarde is, zodat de Where() method weet of je het item wilt toevoegen of niet. Hier is een voorbeeld:
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);
In dit voorbeeld declareren we een tweede lijst met getallen, een soort zwarte lijst van getallen die we niet erbij willen hebben! In de Where() method gebruiken we de Contains() method bij de zwarte lijst om te bepalen of een getal in de eindlijst kan worden opgenomen of niet.
En natuurlijk werkt dat ook bij complexere objecten dan getallen en strings, en is het nog altijd erg gemakkelijk te gebruiken. Kijk naar het voorbeeld waar we objecten met gebruikersinformatie gebruiken in plaats van getallen. We gebruiken de Where() method om een lijst van gebruikers te krijgen waarvan de naam met de letter "J" begint, en met een leeftijd van 39 of jonger:
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; }
}
}
}
En alleen ter vergelijking>> Zie hier hoe de where operatie eruit zou zien als we de query syntaxis hadden gebruikt in plaats van de method syntaxis.
// 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;
Aaneenschakelen van multipele Where() methods
We hebben het hier kort over gehad bij de inleiding van LINQ: Het werkelijke resultaat van een LINQ expressie wordt pas gerealiseerd als je de data echt nodig hebt, bv. wanneer je er een 'loop' op loslaat, het gaat tellen, of gaat herhalen (zoals wij deden in onze voorbeelden). Dat betekent ook dat je multipele Where() methods aan elkaar kunt schakelen als je denkt dat dat beter leesbaar is. Bij zeer complexe expressies kan dat beslist het geval zijn! Hier is een gewijzigde versie van ons vorige voorbeeld:
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);
Het resultaat is precies hetzelfde , en hoewel de eerste versie misschien niet complex genoeg was om de split te rechtvaardigen, kom je naar alle waarschijnlijkheid in situaties waar het verstandig is dat wel te doen. Ik wil benadrukken dat dit in termen van 'performance' niets extra's kost, omdat de echte "where" operatie(s) pas worden uitgevoerd bij het onderdeel waar we een 'loop' uitvoeren bij het resultaat. Tegen die tijd hebben compiler en interpreter jouw query zo snel als mogelijk is geoptimaliseerd, ongeacht hoe je die hebt geschreven.
Samenvatting
Met de Where() method kun je heel gemakkelijk ongewenste items uit je data wegfilteren om een subset van de oorspronkelijke data te maken. Denk eraan dat je inderdaad en nieuwe reeks data krijgt. De oorspronkelijke data bron blijft onberoerd tenzij je de oorspronkelijke variabele overschrijft.