TOC

This article has been localized into Italian by the community.

LINQ:

Ordinare i dati: i metodi OrderBy() e ThenBy()

Così, ora che abbiamo imparato nell'articolo precedente come ottenere dati con LINQ, dalla fonte di dati e filtrarli con il metodo Where(), il prossimo passo potrebbe essere di ordinare i dati. Abbiamo usato liste di oggetti, sia numerici che basati, ad esempio, su una classe User, così l'ordine in cui abbiamo avuto gli elementi era lo stesso in cui erano stati aggiunti alla lista. Tuttavia, come abbiamo detto in precedenza, la nostra fonte di dati per le operazioni con LINQ potrebbe anche essere un documento XML o un database. Perciò, l'abilità di ordinare correttamente i dati, una volta ottenuti, è cruciale. Fortunatamente per noi, LINQ ha diversi metodi di facile utilizzo per ordinare i dati. Proviamo con un esempio semplice:

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);

È stato facile, vero? Basta chiamare il metodo OrderBy() e fornire l'oggetto o il membro dell'oggetto con cui fare l'ordinamento, e viene restituita una lista ordinata. E naturalmente si può fare altrettanto facilmente con le stringhe, come vedremo nel prossimo esempio, ma prendendole in ordine discendente (dal più grande al più piccolo/da Z ad A):

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);

Facciamo la stessa cosa di prima, eccetto che usiamo il metodo OrderByDescending() invece di OrderBy(). Ma naturalmente è facile ordinare una lista di interi e stringhe, un gioco da ragazzi! Comunque, grazie a LINQ, è quasi altrettanto semplice ordinare oggetti più complessi. Ecco un esempio:

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; }
}
    }
}

Questo è un esempio certamente più complesso, con la classe User inclusa e la lista di utenti inizializzata, ma come si può vedere, l'ordinamento effettivo è comunque molto breve e preciso: quando si chiama il metodo OrderBy(), forniamo solo un parametro e poi usiamo questo parametro per accedere alla proprietà Age degli oggetti User. Il risultato è una lista perfettamente ordinata in base all'età. Ma se volessimo ordinare per più di una proprietà?

ThenBy() e ThenByDescending()

Nell'esempio sopra, abbiamo ordinato la lista di utenti in base all'età, ma, e se ci fossero diversi utenti con la stessa età? Uno scenario piuttosto comune, anche per il nostro piccolo esempio. Immaginiamo che Jane e John siano della stessa età e che i loro figli siano gemelli. In questo caso, sarebbe pratico controllare l'ordine anche dopo che i dati sono stati ordinati per età. Per questo, possiamo usare i metodi ThenBy() eThenByDescending(). Fanno proprio quello che dice il nome: controllano l'ordinamento dopo quello iniziale. Li possiamo usare per ottenere la lista di utenti ordinata, prima per età e poi alfabeticamente per nome:

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");

Piuttosto semplice ma molto efficace! Si possono anche concatenare diverse chiamate al metodo ThenBy(), nel caso i dati siano più complessi di quelli del nostro esempio. E naturalmente, si possono mischiare i metodi OrderBy(), OrderByDescending(), ThenBy() e ThenByDescending() in qualunque modo si abbia bisogno:

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");

Stiamo usando principalmente la sintassi di metodo di LINQ in questo tutorial, ma come sempre, prendiamo uno degli esempi nell'articolo e vediamo come si presenta con la sintassi di query. Ecco l'ultimo esempio, includendo una versione con sintassi di query di LINQ:

// 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();

Come si vede, la sintassi è un po' diversa. La direzione (ascendente o discendente) viene specificata direttamente dopo il campo da ordinare (ascendente è di fatto implicito, ma l'ho incluso per mostrare la differenza). Inoltre, non c'è "ThenBy". Al suo posto, si usano istruzioni multiple separate da una virgola. Naturalmente, alla fine, entrambe le espressioni danno lo stesso risultato.

Riepilogo

Usando i metodi OrderBy() e ThenBy() (come anche le controparti "discendenti") ci permette di ordinare facilmente i dati nella maniera desiderata. Va ricordato che, come ogni altro metodo LINQ, i dati di origine non vengono modificati. Invece, si ottiene una copia ordinata dell'originale, con cui lavorare.


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!