TOC

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

LINQ:

Sorting data: the OrderBy() & ThenBy() methods

Chúng ta đã học ở bài trước về cách lấy dữ liệu từ nguồn dữ liệu với LINQ và lọc nó với Where(), bước tiếp theo là sắp xếp dữ liệu. Chúng ta dùng danh sách các đối tượng, hay thậm chí cả số hay dựa trên ví dụ lớp User, vì vậy thứ tự chúng ta có các thành phần giống chúng ta đưa vào trong danh sách. Tuy nhiên, như chúng ta đã nói, nguồn dữ liệu của bạn trong LINQ có thể là XML hay cơ sở dữ liệu. Do đó, khả năng sắp xếp dữ liệu là cần theiets. May cho chúng ta, LINQ có nhiều phương thức dễ dùng để sắp xếp - hãy xem ví dụ cơ bản này đầu tiên:

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

Rất đơn giản đúng không? Chỉ cần gọi phương thức OrderBy() và đưa vào đó đối tượng hay thành phần của đối tượng để sắp xếp, khi đó danh sách được sắp xếp sẽ trả về. Và tất nhiên bạn có thể đưa vào đơn giản là chuỗi, như chúng ta thấy trong ví dụ tiếp theo nhưng hãy sắp xếp theo thứ tự giảm dần (từ lớn nhất đến nhỏ nhất/ từ Z tới 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);

Chúng ta làm giống hệt phần trước, ngoại trừ việc dùng OrderByDescending() thay vì OrderBy(). Nhưng tất nhiên bạn có thể sắp xếp danh sách số nguyên và chuỗi dễ dàng. Tuy nhiên, nhờ có LINQ, rất dễ để sắp xếp nhiều đối tượng phức tạp hơn. Ví dụ:

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

Đây tất nhiên là một ví dụ hoàn chỉnh hơn, với lớp User và danh sách user nhưng bạn có thể thấy, sắp xếp đơn giản: khi gọi OrderBy() chúng ta chỉ cần truyền tham số là user và sau đó dùng tham số này để truy cập vào thuộc tính Age của đối tượng User. Kết quả trả về danh sách tuổi được sắp xếp! Nhưng nếu chúng ta muốn sắp xếp nhiều hơn một thuộc tính thì sao?

ThenBy() and ThenByDescending()

Ở ví dụ trên, chúng ta sắp xếp danh sách user theo tuổi nhưng nếu có nhiều user cùng tuổi? Một kịch bản chung như Jane và John có cùng tuổi và họ là anh em sinh đôi. Trong trường hợp này, chúng ta dùng ThenBy()ThenByDescending(). Đúng như cái tên chỉ ra: Sắp xếp thứ tự sau khi đã được sắp xếp. Chúng ta có thể dùng để có danh sách của user sắp xếp theo tuổi và sau đó là tên:

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

Rất đơn giản và hiệu quả! Bạn có thể có một chuỗi ThenBy(), trong trường hợp dữ liệu của bạn phức tạp hơn ví dụ. Và tất nhiên bạn có thể sắp xếp và kết hợp OrderBy(), OrderByDescending(), ThenBy() và ThenByDescending() theo cách mà bạn muốn:

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

Chúng ta dùng cú pháp phương thức của LINQ trong bài giảng nhưng như thường lệ, tôi sẽ lấy một ví dụ trong bài và chỉ cho bạn cú pháp truy vấn trông ra sao - đây là ví dụ có cả cú pháp truy vấn 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();

Như bạn thấy, cú pháp hơi khác một chút - cách sắp xếp (tăng hay giảm) được chỉ định trực tiếp sau khi trường để sắp xếp (tăng là mặc định, nhưng tôi viết ra để chỉ cho bạn sự khác việt). Cũng như vậy, có "Then By" - bạn chỉ chia các chỉ dẫn sắp xếp với dấu phẩy. Tất nhiên, cuối cùng, cả hai sẽ cho bạn cùng kết quả.

Summary

Dùng cả OrderBy()ThenBy() (cũng như là "descending"), bạn có thể dễ dàng lấy dữ liệu được sắp xếp theo cách bạn muốn. Và nhớ là giống các phương thức LINQ khác, dữ liệu thực sự không thay đổi - thay vì đó, bạn có bản sao dữ liệu và bạn có thể làm việc với nó.


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!