This article has been localized into Spanish by the community.
Ordenar datos: los métodos OrderBy () y ThenBy ()
Entonces, ahora que hemos aprendido a través del artículo anterior cómo obtener datos del origen de datos con LINQ y filtrarlos con el método Where (), el siguiente paso podría ser ordenar los datos. Hemos utilizado listas de objetos, numéricos o basados en p. una clase de usuario, por lo que el orden en que obtuvimos los artículos era el mismo orden en que se agregaron a la lista. Sin embargo, como hemos mencionado anteriormente, su fuente de datos para las operaciones de LINQ también podría ser un documento XML o una base de datos. Por lo tanto, la capacidad de ordenar adecuadamente los datos, una vez que tenemos los datos que necesitamos, es crucial. Afortunadamente para nosotros, LINQ tiene varios métodos fáciles de usar para ordenar datos. Probemos primero con un ejemplo básico:
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);
Eso fue fácil, ¿verdad? Simplemente llame al método OrderBy () y proporcione el objeto o el miembro del objeto para ordenar, y se devolverá una lista ordenada. Y, por supuesto, puede hacerlo igual de fácil con las cadenas, como veremos en el siguiente ejemplo, pero obtengamos los elementos en orden descendente (de mayor a menor / de Z a 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);
Hacemos exactamente lo mismo que antes, excepto que usamos el método OrderByDescending () en lugar del método OrderBy (). Pero, por supuesto, puede ordenar su lista de enteros y cadenas fácilmente, ¡eso es pan comido! Sin embargo, gracias a LINQ, es casi igual de fácil clasificar objetos más complejos. Aquí hay un ejemplo:
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; }
}
}
}
Por supuesto, este es un ejemplo más completo, con la clase de usuario incluida y la lista de usuarios inicializada, pero como puede ver, la clasificación real sigue siendo muy breve y precisa: al llamar al método OrderBy (), solo proporcionamos un nombre del parámetro y luego use este parámetro para acceder a la propiedad Age de los objetos Usuario. ¡El resultado es una lista perfectamente ordenada por edad! Pero, ¿qué pasa si queremos ordenar por más de una propiedad?
ThenBy() y ThenByDescending()
En el ejemplo anterior, clasificamos la lista de usuarios por edad, pero ¿y si hubiera varios usuarios de la misma edad? Un escenario bastante común, incluso en nuestro pequeño ejemplo: imagínense que Jane y John tienen la misma edad y que sus hijos son gemelos. En ese caso, sería práctico controlar el pedido incluso después de que la fuente de datos se hubiera organizado por edad. Para eso, podemos usar los métodos ThenBy () y ThenByDescending () . Hacen exactamente lo que indica el nombre: controlan el orden después de la clasificación inicial. Podemos usar eso para ordenar la lista de usuarios, primero por edad y luego alfabéticamente por nombre:
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");
¡Muy simple pero muy efectivo! Incluso puede encadenar varias llamadas al método ThenBy (), en caso de que sus datos sean más complejos que los de nuestro caso de prueba. Y, por supuesto, puede mezclar y combinar los métodos OrderBy (), OrderByDescending (), ThenBy () y ThenByDescending () de la forma que necesite:
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");
En este tutorial usamos principalmente la sintaxis basada en métodos de LINQ, pero, como siempre, tomaré uno de los ejemplos del artículo y le mostraré cómo se vería con la sintaxis de consulta. Aquí está el último ejemplo, que incluye una versión utilizando LINQ query syntax.
// 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();
Como puede ver, la sintaxis es ligeramente diferente: la dirección (ascendente o descendente) se especifica directamente después del campo para ordenar por (ascendente en realidad está implícito, pero lo incluí para mostrarle la diferencia). Además, no hay "ThenBy"; en su lugar, simplemente separa varias instrucciones de clasificación con una coma. Por supuesto, al final, ambas consultas le darán el mismo resultado.
Resumen.
Usando los métodos OrderBy () y ThenBy () (así como sus contrarios"descendentes"), puede ordenar fácilmente sus datos de la manera que desee. Y recuerde, al igual que cualquier otro método LINQ, la fuente de datos real no se manipula; en su lugar, obtiene una copia ordenada de la fuente de datos original, con la que puede trabajar.