TOC

This article is currently in the process of being translated into Dutch (~99% done).

LINQ:

Sorteren van data: de OrderBy() & ThenBy() methods

Nu we vanuit het vorige artikel geleerd hebben om gegevens (data) uit de data bron te halen via LINQ en die te filteren met de Where() method, dan zou de volgende stap het sorteren van data kunnen zijn. We hebben lijsten van objecten gebruikt, zowel numerieke als gebaseerd op bv. een User class. Dus de volgorde waarin de items binnenkregen, was dezelfde als waarmee ze aan de lijst waren toegevoegd. Echter, Daarom is de mogelijkheid om de data goed te sortrenzoals eerder besproken, kan jouw data bron voor LINQ operaties zowel een XML document zijn als een database. Daarom is de mogelijkheid om data goed te sorteren cruciaal. Gelukkig heeft LINQ een aantal gemakkelijk te gebruiken methods om data te sorteren. We proberen er een paar:

List<int> numbers = new List<int>()
{
    1, 7, 2, 61, 14
};
List<int> sortedNumbers = numbers.OrderBy(number => number).ToList();
foreach (int number in sortedNumbers)
    Console.WriteLine(number);

Dat was gemakkelijk, nietwaar? Roep de OrderBy() method aan en doe er het te sorteren object of het lid van het object bij, en je krijgt er een gesorteerde lijst van terug. En natuurlijk kun je dat net ze gemakkelijk doen met strings, zoals we zullen zien in het volgende voorbeeld. Maar laten we de items in aflopende (grootste naar kleinste/ van Z naar A) volgorde zetten:

List<string> cityNames = new List<string>()
{
    "Amsterdam", "Berlin", "London", "New York"
};
List<string> sortedCityNames = cityNames.OrderByDescending(city => city).ToList();
foreach (string cityName in sortedCityNames)
    Console.WriteLine(cityName);

We doen hetzelfde als zojuist maar nu gebruiken we niet de OrderBy() method maar de OrderByDescending() method. En natuurlijk kun je je lijst van integers en strings gemakkelijk gesorteerd krijgen, dat stelt niks voor! Maar dankzij LINQ is het vrijwel net zo gemakkelijk om complexere objecten te sorteren. Hier is een voorbeeld:

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqOrder2
{
    class Program
    {
static void Main(string[] args)
{
    List<User> listOfUsers = new List<User>()
    {
new User() { Name = "John Doe", Mail = "john@doe.com", Age = 42 },
new User() { Name = "Jane Doe", Mail = "jane@doe.com", Age = 34 },
new User() { Name = "Joe Doe", Mail = "joe@doe.com", Age = 8 },
new User() { Name = "Another Doe", Mail = "another@doe.com", Age = 15 },
    };

    List<User> usersByAge = listOfUsers.OrderBy(user => user.Age).ToList();
    foreach (User user in usersByAge)
Console.WriteLine(user.Name + ": " + user.Age + " years");
}

class User
{
    public string Name { get; set; }
    public string Mail { get; set; }
    public int Age { get; set; }
}
    }
}

Dit is natuurlijk een completer voorbeeld, met de User class en een geïnitialiseerde lijst van gebruikers, maar zoals je kunt zien, is het sorteren nog steeds erg kort en precies: Bij het aanroepen van de OrderBy() method, leveren we alleen maar een naam van een parameter en gebruiken vervolgens deze parameter om toegang te krijgen tot de Age property van de User objects. Het resultaat is een perfect op naam gesorteerde lijst! Maar wat te doen als we als we met meer dan één property willen ordenen?

ThenBy() en ThenByDescending()

In bovenstaand voorbeeld sorteerden we de lijst van gebruikers naar leeftijd. Maar als er nu enkele gebruikers zijn met dezelfde leeftijd? Een tamelijk voorkomend scenario, zelfs in ons kleine voorbeeld. Stel dat Jane en John even oud zijn en hun kinderen zijn tweelingen. Dan zou het praktisch zijn om de volgorde te kunnen bepalen zelfs nadat de databron op leeftijd was gezet. Hiervoor kunnen we de ThenBy() en ThenByDescending() methods gebruiken. Ze doen precies wat de naam zegt: Bepaal de volgorde na een initiële sortering. We kunnen dat gebruiken om de lijst van gebruikers éérst op leeftijd en daarna alfabetisch op naam te sorteren.

List<User> listOfUsers = new List<User>()
{
    new User() { Name = "John Doe", Mail = "john@doe.com", Age = 42 },
    new User() { Name = "Jane Doe", Mail = "jane@doe.com", Age = 42 },
    new User() { Name = "Joe Doe", Mail = "joe@doe.com", Age = 8 },
    new User() { Name = "Jenna Doe", Mail = "another@doe.com", Age = 8 },      
};

List<User> sortedUsers = listOfUsers.OrderBy(user => user.Age).ThenBy(user => user.Name).ToList();
foreach (User user in sortedUsers)
    Console.WriteLine(user.Name + ": " + user.Age + " years");

Simpel maar heel effectief! Je kunt zelfs multipele ThenBy() method calls schakelen, voor het geval jouw data complexer zijn dan de data uit onze test case. En natuurlijk kun je de OrderBy(), OrderByDescending(), ThenBy() en ThenByDescending() methods mixen en vergelijken hoe je maar wilt:

List<User> sortedUsers = listOfUsers.OrderBy(user => user.Age).ThenByDescending(user => user.Name).ToList();
foreach (User user in sortedUsers)  
    Console.WriteLine(user.Name + ": " + user.Age + " years");

We gebruiken meestal de methode-gebaseerde syntaxis van LINQ in deze tutorial, maar zoals altijd, neem ik nu één van de voorbeelden in het artikel en laat je zien hoe het eruit zou zien met de query syntaxis. Hier is het laatste voorbeeld met de LINQ query syntax versie:

// Method syntax
List<User> sortedUsers = listOfUsers.OrderBy(user => user.Age).ThenByDescending(user => user.Name).ToList();

// Query syntax
List<User> sortedUsersQ = (from user in listOfUsers orderby user.Age ascending, user.Name descending select user).ToList();

Zoals je ziet is de syntaxis enigszins verschillend. De richting (stijgend of dalend/ascending or descending) worst direct gespecificeerd na het veld volgens welk geordend moet worden (ascending is eigenlijk impliciet, maar ik zette het erbij om het verschil te laten zien). Er is ook geen "ThenBy" in plaats daarvan. je hoeft alleen maar multipele sorteerinstructies met een komma te scheiden. Natuurlijk leveren beide queries uiteindelijk hetzelfde resultaat.

Summary

Met behulp van de OrderBy() en ThenBy() methods (zowel als met hun "descending" tegenhangers), kun je gemakkelijk data sorteren zoals jij dat wilt. En denk eraan dat net als bij elke andere LINQ method de actuele databron niet verandert. In plaats daarvan krijg je een gesorteerde kopie van de originele databron, waarmee je aan het werk kunt.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!