ZetCode

C# LINQ 排序

上次修改时间:2024 年 1 月 23 日

在本文中,我们将展示如何使用 LINQ 查询在 C# 中对数据进行排序。

语言集成查询 (LINQ) 是一种特定领域的语言,用于查询来自各种数据源的数据,包括数组、列表、XML 文件或数据库。

我们可以使用 LINQ 的 OrderOrderDescendingOrderByOrderByDescending 方法对数据进行排序。这些方法不会改变原始序列;它们返回一个新的排序后的序列。

此外,我们可以将 orderbyascendingdescending 子句与 LINQ 查询表达式一起使用。

C# LINQ 排序

Order 方法按升序对序列的元素进行排序。

Order<T>(IEnumerable<T>)
Order<T>(IEnumerable<T>, IComparer<T>)

第二个方法接受一个 IComparer

Program.cs
List<string> words = [
    "world", "War", "abbot", "Caesar", "castle", "sky", "den",
    "forest", "ocean", "water", "falcon", "owl", "rain", "Earth"
];

var sorted = words.Order().ToList();
sorted.ForEach(Console.WriteLine);

Console.WriteLine("-------------------------");

var sorted2 = words.Order(StringComparer.Ordinal).ToList();
sorted2.ForEach(Console.WriteLine);

我们有一个单词列表。我们按升序对单词进行排序。

var sorted = words.Order().ToList();
sorted.ForEach(Console.WriteLine);

我们使用 Order 对单词进行排序,并将排序后的结果打印到控制台。单词以不区分大小写的方式排序。

var sorted2 = words.Order(StringComparer.Ordinal).ToList();
sorted2.ForEach(Console.WriteLine);

对于重载的方法,我们还传递一个字符串比较器。 StringComparer.Ordinal 使单词以区分大小写的方式排序。

$ dotnet run
abbot
Caesar
castle
den
Earth
falcon
forest
ocean
owl
rain
sky
War
water
world
-------------------------
Caesar
Earth
War
abbot
castle
den
falcon
forest
ocean
owl
rain
sky
water
world

C# LINQ OrderDescending

OrderDescending 方法按降序对序列的元素进行排序。

Program.cs
List<int> vals = [0, -2, 1, -3, 4, 3, 2, 5, 7, -1]; 

var sorted = vals.OrderDescending();
Console.WriteLine(string.Join(", ", sorted));

在程序中,我们按降序对整数进行排序。

$ dotnet run
7, 5, 4, 3, 2, 1, 0, -1, -2, -3

C# LINQ OrderBy

OrderBy 方法根据键按升序对序列的元素进行排序。

OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

该方法接受一个 keyselector 函数,该函数从元素中提取一个键。

Program.cs
List<User> users =
[
    new ("John", "Doe", 1230),
    new ("Lucy", "Novak", 670),
    new ("Ben", "Walter", 2050),
    new ("Robin", "Brown", 2300),
    new ("Amy", "Doe", 1250),
    new ("Joe", "Draker", 1190),
    new ("Janet", "Doe", 980),
    new ("Albert", "Novak", 1930),
];

Console.WriteLine("sort ascending by last name and salary");

var sortedUsers = users.OrderBy(u => u.LastName).ThenBy(u => u.Salary);

foreach (var user in sortedUsers)
{
    Console.WriteLine(user);
}

record User(string FirstName, string LastName, int Salary);

在该示例中,我们首先按用户的姓氏对用户进行排序,然后按他们的薪水进行排序。

var sortedUsers = users.OrderBy(u => u.LastName).ThenBy(u => u.Salary);

我们按用户的姓氏对用户进行排序,然后按他们的薪水进行升序排序。 Lambda 形式的 keyselector 函数提取 LastName 属性作为排序键。

$ dotnet run
sort ascending by last name and salary
User { FirstName = Robin, LastName = Brown, Salary = 2300 }
User { FirstName = Janet, LastName = Doe, Salary = 980 }
User { FirstName = John, LastName = Doe, Salary = 1230 }
User { FirstName = Amy, LastName = Doe, Salary = 1250 }
User { FirstName = Joe, LastName = Draker, Salary = 1190 }
User { FirstName = Lucy, LastName = Novak, Salary = 670 }
User { FirstName = Albert, LastName = Novak, Salary = 1930 }
User { FirstName = Ben, LastName = Walter, Salary = 2050 }

C# LINQ OrderByDescending

OrderByDescending 方法按降序对序列的元素进行排序。

Program.cs
List<User> users =
[
    new ("John", "Doe", 1230),
    new ("Lucy", "Novak", 670),
    new ("Ben", "Walter", 2050),
    new ("Robin", "Brown", 2300),
    new ("Amy", "Doe", 1250),
    new ("Joe", "Draker", 1190),
    new ("Janet", "Doe", 980),
    new ("Albert", "Novak", 1930),
];

Console.WriteLine("sort descending by last name and salary");

var sortedUsers = users.OrderByDescending(u => u.LastName)
    .ThenByDescending(u => u.Salary);

foreach (var user in sortedUsers)
{
    Console.WriteLine(user);
}

record User(string FirstName, string LastName, int Salary);

在程序中,我们按姓氏对用户进行排序,然后按薪水降序排序。

$ dotnet run
sort descending by last name and salary
User { FirstName = Ben, LastName = Walter, Salary = 2050 }
User { FirstName = Albert, LastName = Novak, Salary = 1930 }
User { FirstName = Lucy, LastName = Novak, Salary = 670 }
User { FirstName = Joe, LastName = Draker, Salary = 1190 }
User { FirstName = Amy, LastName = Doe, Salary = 1250 }
User { FirstName = John, LastName = Doe, Salary = 1230 }
User { FirstName = Janet, LastName = Doe, Salary = 980 }
User { FirstName = Robin, LastName = Brown, Salary = 2300 }

使用查询表达式排序

下一个示例使用 LINQ 查询表达式来对数据进行排序。

Program.cs
List<string> words = [
    "world", "War", "abbot", "Caesar", "castle", "sky", "den",
    "forest", "ocean", "water", "falcon", "owl", "rain", "Earth"
];

var sorted = from word in words
             orderby word
             select word;

Console.WriteLine(string.Join(", ", sorted));

var sorted2 = from word in words
              orderby word descending
              select word;

Console.WriteLine(string.Join(", ", sorted2));

我们使用 orderbydescending 子句对单词列表进行排序。

$ dotnet run
abbot, Caesar, castle, den, Earth, falcon, forest, ocean, owl, rain, sky, War, water, world
world, water, War, sky, rain, owl, ocean, forest, falcon, Earth, den, castle, Caesar, abbot

连接和排序

在下一个示例中,我们对连接操作执行排序操作。

Program.cs
List<Country> countries =
[
    new("Slovakia", 1),
    new("Hungary", 2),
    new("Russia", 3),
    new("Poland", 4)
];

List<City> cities =
[
    new("Bratislava", 1),
    new("Poprad", 1),
    new("Trnava", 1),
    new("Budapest", 2),
    new("Miskolc", 2),
    new("Ajka", 2),
    new("Moscow", 3),
    new("Jakutsk", 3),
    new("Perm", 3),
    new("Omsk", 3),
    new("Warsaw", 4),
    new("Krakow", 4),
];


var groups =
    from country in countries
    join city in cities on country.Id equals city.CountryId into cGroup
    orderby country.Name
    select new
    {
        Country = country.Name,
        Cities =
            from city2 in cGroup
            orderby city2.Name
            select city2
    };

foreach (var group in groups)
{
    Console.WriteLine(group.Country);

    foreach (var city in group.Cities)
    {
        Console.WriteLine($"  {city.Name}");
    }
}

record City(string Name, int CountryId);
record Country(string Name, int Id);

我们有国家及其对应的城市。我们将城市与其国家连接起来。我们按升序输出城市,并且国家内的城市也按升序输出。

var groups =
    from country in countries
    join city in cities on country.Id equals city.CountryId into cGroup
    orderby country.Name
    select new
    {
        Country = country.Name,
        Cities =
            from city2 in cGroup
            orderby city2.Name
            select city2
    };

我们将城市与其国家连接起来。 键是国家/地区 ID。 我们使用 orderby 对国家/地区和城市进行排序。

foreach (var group in groups)
{
    Console.WriteLine(group.Country);

    foreach (var city in group.Cities)
    {
        Console.WriteLine($"  {city.Name}");
    }
}

我们遍历这些组并打印每个国家及其城市。

$ dotnet run 
  Hungary
    Ajka
    Budapest
    Miskolc
  Poland
    Krakow
    Warsaw
  Russia
    Jakutsk
    Moscow
    Omsk
    Perm
  Slovakia
    Bratislava
    Poprad
    Trnava

来源

Enumerable.OrderBy 方法

在本文中,我们使用 LINQ 在 C# 中对数据进行了排序。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程