C# 排序 List
最后修改于 2024 年 1 月 31 日
C# 排序列表教程展示了如何在 C# 语言中对列表元素进行排序。
排序
在计算机科学中,排序是将元素按顺序排列。 多年来,已经开发了几种算法来对数据进行排序,包括归并排序、快速排序、选择排序或冒泡排序。(排序的另一个含义是分类;它是将具有相似属性的元素分组。)
排序的相反操作,即将元素序列重新排列成随机或无意义的顺序,称为洗牌。
数据可以按字母或数字顺序排序。排序键指定用于执行排序的标准。 可以通过多个键对对象进行排序。 例如,在对用户进行排序时,可以使用用户的姓名作为主排序键,并将其职业作为辅助排序键。
Sort 方法对列表元素进行排序,或者使用 LINQ 的 OrderBy。排序顺序
标准顺序称为升序:a 到 z,0 到 9。相反的顺序称为降序:z 到 a,9 到 0。对于日期和时间,升序意味着较早的值先于较晚的值,例如 1/1/2020 将排在 1/1/2021 之前。
稳定排序
稳定排序是指保持相等元素的初始顺序。 有些排序算法自然是稳定的,有些是不稳定的。 例如,归并排序和冒泡排序是稳定的排序算法。 另一方面,堆排序和快速排序是不稳定的排序算法的示例。
考虑以下值:3715593。 稳定排序产生以下结果:1335579。 值 3 和 5 的顺序被保留。 不稳定排序可能会产生以下结果:1335579。
C# 内部使用稳定的排序算法。
C# 中的排序
在 C# 中,我们可以使用内置的 Sort/OrderBy 方法以及 Comparison 委托、IComparer 和 IComparable 接口进行排序。
C# List Sort 方法
Sort 方法对列表中的元素或一部分元素进行排序。
该方法有四个重载
- Sort(Comparison<T>) - 使用指定的 Comparison<T> 对整个 List<T> 中的元素进行排序。
- Sort(Int32, Int32, IComparer<T>) - 使用指定的比较器对 List<T> 中某个范围内的元素进行排序。
- Sort() - 使用默认比较器对整个 List<T> 中的元素进行排序。
- Sort(IComparer<T>) - 使用指定的比较器对整个 List<T> 中的元素进行排序。
Sort 方法对列表进行就地排序,而 LINQ 的 OrderBy 方法返回列表元素的排序枚举。比较方法
排序算法已经内置在语言的标准库中。如果数据不是自然排序的,我们需要提供一个比较方法(类方法或 lambda 表达式),告诉底层的排序算法如何对数据进行排序。要排序的属性以及排序方式。
public int CompareTo(Card other)
{
var index = Rank.CompareTo(other.Rank);
if (index == 0) index = Suit.CompareTo(other.Suit);
return index;
}
例如,这个比较类方法告诉我们按 Rank 对对象进行排序,如果 rank 相同,则按 Suit 排序。我们总是比较两个元素;在我们的例子中,是两个卡片对象。如果元素相等,比较方法返回 0;如果第一个元素小于第二个元素,返回 -1;如果第一个元素大于第二个元素,返回 1。
通常,我们的比较函数会调用其他的比较函数;在我们的例子中,Rank 和 Suit 都是枚举,我们使用内置的 CompareTo 方法来比较它们。
C# List 排序整数
以下示例对整数进行排序。
List<int> nums = [2, 1, 8, 0, 4, 3, 5, 7, 9];
nums.Sort();
Console.WriteLine(string.Join(",", nums));
nums.Reverse();
Console.WriteLine(string.Join(",", nums));
C# 使用默认的比较器方法对整数进行数值排序。Sort 方法按升序对整数进行排序,而 Reverse 方法按降序排序。
$ dotnet run 0,1,2,3,4,5,7,8,9 9,8,7,5,4,3,2,1,0
以下示例使用 LINQ 对整数进行排序。在 LINQ 中,我们可以选择查询语法或方法语法。
List<int> nums = [2, 1, 8, 0, 4, 3, 5, 7, 9];
var enum1 = from num in nums
orderby num
select num;
foreach (var e in enum1)
{
Console.Write($"{e} ");
}
Console.WriteLine();
var enum2 = from num in nums
orderby num descending
select num;
foreach (var e in enum2)
{
Console.Write($"{e} ");
}
Console.WriteLine();
该示例使用 LINQ 的查询语法按升序和降序对整数进行排序。
$ dotnet run 0 1 2 3 4 5 7 8 9 9 8 7 5 4 3 2 1 0
C# List 排序字符串
与整数一样,字符串默认情况下按字母顺序通过 Sort 排序,无需额外操作。
List<string> words = ["falcon", "order", "war",
"sky", "ocean", "blue", "cloud", "boy"];
words.Sort();
Console.WriteLine(string.Join(",", words));
words.Reverse();
Console.WriteLine(string.Join(",", words));
该示例按升序和降序对字符串进行排序。
$ dotnet run blue,boy,cloud,falcon,ocean,order,sky,war war,sky,order,ocean,falcon,cloud,boy,blue
C# List 排序带重音符号的字符串
为了对带有重音符号的字符串进行排序,我们需要提供适当的 CultureInfo。
using System.Globalization;
Console.OutputEncoding = System.Text.Encoding.UTF8;
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK");
List<string> words = [ "čaj", "auto", "drevo", "cibuľa",
"čučoriedka", "banán", "čerešňa", "červený", "čierny", "cesnak" ];
words.Sort();
foreach (var word in words)
{
Console.WriteLine(word);
}
该示例对斯洛伐克语单词进行排序。斯洛伐克语有许多带重音符号的字符,例如 č 或 ň。
$ dotnet run auto banán cesnak cibuľa čaj čerešňa červený čierny čučoriedka drevo
这些单词根据斯洛伐克规范正确排序。
C# List 按字符串长度排序
以下示例按单词的长度对单词列表进行排序。
List<string> words = ["falcon", "order", "war",
"sky", "ocean", "blue", "cloud", "boy", "by", "raven",
"station", "batallion"];
words.Sort((a, b) => a.Length.CompareTo(b.Length));
Console.WriteLine(string.Join(",", words));
words.Sort((a, b) => b.Length.CompareTo(a.Length));
Console.WriteLine(string.Join(",", words));
我们需要提供我们自己的比较方法来完成这项工作。
words.Sort((a, b) => a.Length.CompareTo(b.Length));
Console.WriteLine(string.Join(",", words));
我们为 Sort 方法提供了一个匿名方法。此方法使用整数类型的 CompareTo 方法来比较两个值。单词的长度使用 Length 属性返回。
$ dotnet run by,war,sky,boy,blue,order,ocean,cloud,raven,falcon,station,batallion batallion,station,falcon,order,ocean,cloud,raven,blue,war,sky,boy,by
以下示例使用 LINQ 执行相同的操作。
List<string> words = ["falcon", "order", "war",
"sky", "ocean", "blue", "cloud", "boy", "by", "raven",
"station", "batallion"];
var res = from word in words
orderby word.Length
ascending
select word;
foreach (var word in res)
{
Console.WriteLine(word);
}
var res2 = from word in words
orderby word.Length
descending
select word;
foreach (var word in res2)
{
Console.WriteLine(word);
}
在该示例中,我们使用 LINQ 查询表达式按长度升序和降序对单词进行排序。
C# List 按姓氏排序姓名
当我们要按姓氏对姓名进行排序时,假设整个姓名是一个字符串,我们需要提供一个自定义的比较方法。
List<string> names = ["John Doe", "Lucy Smith",
"Benjamin Young", "Robert Brown", "Thomas Moore",
"Linda Black", "Adam Smith", "Jane Smith"];
names.Sort((n1, n2) => n1.Split(" ")[1].CompareTo(n2.Split(" ")[1]));
Console.WriteLine(string.Join(",", names));
为了解决这个问题,我们将字符串分成两个部分,并在 lambda 表达式中比较字符串的第二部分。
$ dotnet run Linda Black Robert Brown John Doe Thomas Moore Lucy Smith Adam Smith Jane Smith Benjamin Young
请注意,Smiths 的顺序保持不变;这是稳定排序算法的一个例子。
以下示例提供了一个 LINQ 解决方案。
List<string> names = ["John Doe", "Lucy Smith",
"Benjamin Young", "Robert Brown", "Thomas Moore",
"Linda Black", "Adam Smith", "Jane Smith"];
var res = from name in names
orderby name.Split(" ")[1]
ascending
select name;
foreach (var name in res)
{
Console.WriteLine(name);
}
该示例使用 LINQ 查询表达式语法按姓氏对姓名进行排序。
C# List 排序不区分大小写
要以不区分大小写的方式比较字符串,我们可以使用内置的 StringComparer.OrdinalIgnoreCase。
List<string> words =
[
"world", "War", "abbot", "Caesar", "castle", "sky", "den",
"forest", "ocean", "water", "falcon", "owl", "rain", "Earth"
];
words.Sort(StringComparer.OrdinalIgnoreCase);
words.ForEach(Console.WriteLine);
该示例对单词列表进行不区分大小写的排序。
$ dotnet run abbot Caesar castle den Earth falcon forest ocean owl rain sky War water world
C# List 使用 Comparison 排序
Comparison 委托表示比较相同类型的两个对象的方法。
List<(string, int)> employees =
[
("John Doe", 1230),
("Adam Novak", 670),
("Robin Brown", 2300),
("Rowan Cruise", 990),
("Joe Draker", 1190),
("Janet Doe", 980),
("Lucy Smith", 980),
("Thomas Moore", 1400)
];
employees.Sort(delegate ((string, int) emp1, (string, int) emp2)
{
return emp1.Item2.CompareTo(emp2.Item2);
});
Console.WriteLine(string.Join(Environment.NewLine, employees));
在该示例中,我们使用匿名委托对用户列表进行排序。 用户按薪水升序排序。
$ dotnet run (Adam Novak, 670) (Janet Doe, 980) (Lucy Smith, 980) (Rowan Cruise, 990) (Joe Draker, 1190) (John Doe, 1230) (Thomas Moore, 1400) (Robin Brown, 2300)
在下一个示例中,我们将委托更改为 lambda 表达式。
List<(string, int)> employees =
[
("John Doe", 1230),
("Adam Novak", 670),
("Robin Brown", 2300),
("Rowan Cruise", 990),
("Joe Draker", 1190),
("Janet Doe", 980),
("Lucy Smith", 980),
("Thomas Moore", 1400)
];
employees.Sort((e1, e2) =>
{
return e2.Item2.CompareTo(e1.Item2);
});
Console.WriteLine(string.Join(Environment.NewLine, employees));
在该示例中,用户按薪水降序排序。
$ dotnet run (Robin Brown, 2300) (Thomas Moore, 1400) (John Doe, 1230) (Joe Draker, 1190) (Rowan Cruise, 990) (Janet Doe, 980) (Lucy Smith, 980) (Adam Novak, 670)
C# List 使用 IComparable 排序
IComparable 接口定义了一个通用的特定于类型的比较方法,值类型或类实现该方法来排序或对其实例进行排序。
IComparable 接口最适合于较小的、紧凑的类型,它们的排序很明显。
List<Employee> employees =
[
new ("John Doe", 1230),
new ("Adam Novak", 670),
new ("Robin Brown", 2300),
new ("Rowan Cruise", 990),
new ("Joe Draker", 1190),
new ("Janet Doe", 980),
new ("Lucy Smith", 980),
new ("Thomas Moore", 1400)
];
employees.Sort();
Console.WriteLine(string.Join(Environment.NewLine, employees));
record Employee(string Name, int Salary) : IComparable<Employee>
{
public int CompareTo(Employee? other)
{
if (other == null) return 1;
return other.Salary.CompareTo(Salary);
}
};
我们有一个 Employee 记录,其中包含一个内置的比较方法,该方法按薪水升序对员工进行排序。
$ dotnet run
Employee { Name = Robin Brown, Salary = 2300 }
Employee { Name = Thomas Moore, Salary = 1400 }
Employee { Name = John Doe, Salary = 1230 }
Employee { Name = Joe Draker, Salary = 1190 }
Employee { Name = Rowan Cruise, Salary = 990 }
Employee { Name = Janet Doe, Salary = 980 }
Employee { Name = Lucy Smith, Salary = 980 }
Employee { Name = Adam Novak, Salary = 670 }
C# List 使用 IComparer 排序
IComparer 接口定义了一个比较方法,值类型或类实现该方法来排序或对其实例进行排序。
使用 IComparer,我们拥有更大的灵活性;我们可以定义多个比较器或更新现有的比较器,而无需触及类型本身。 此外,它具有更简洁的设计,因为我们将排序实现与类型分开。
List<(string, int)> employees =
[
("John Doe", 1230),
("Adam Novak", 670),
("Robin Brown", 2300),
("Rowan Cruise", 990),
("Joe Draker", 1190),
("Janet Doe", 980),
("Lucy Smith", 980),
("Thomas Moore", 1400)
];
employees.Sort(new SurnameComparer());
employees.ForEach(employee => Console.WriteLine(employee));
class SurnameComparer : IComparer<(string, int)>
{
public int Compare((string, int) e1, (string, int) e2)
{
return e1.Item1.Split()[1].CompareTo(e2.Item1.Split()[1]);
}
}
在该示例中,我们按姓氏对员工进行排序。
$ dotnet run (Robin Brown, 2300) (Rowan Cruise, 990) (John Doe, 1230) (Janet Doe, 980) (Joe Draker, 1190) (Thomas Moore, 1400) (Adam Novak, 670) (Lucy Smith, 980)
C# List 排序元组
以下示例对元组列表进行排序。
List>(string Name, int Grade)> data =
[
("Patrick", 89),
("Lucia", 92),
("Veronika", 72),
("Robert", 78),
("Maria", 65),
("Andrea", 51),
("Ondrej", 45)
];
data.Sort((s1, s2) => s1.Grade.CompareTo(s2.Grade));
Console.WriteLine(string.Join(", ", data));
data.Sort((s1, s2) => s2.Grade.CompareTo(s1.Grade));
Console.WriteLine(string.Join(", ", data));
在该示例中,我们有一个表示学生及其成绩的元组列表。 我们按成绩升序和降序对元组进行排序。
$ dotnet run (Ondrej, 45), (Andrea, 51), (Maria, 65), (Veronika, 72), (Robert, 78), ... (Lucia, 92), (Patrick, 89), (Robert, 78), (Veronika, 72), (Maria, 65), ...
C# List 排序对象
在以下示例中,我们对 User 对象列表进行排序。
List<User> users = [
new ("John", "Doe", 1230),
new ("John", "Doe", 1230),
new ("Lucy", "Novak", 670),
new ("Ben", "Walter", 2050),
new ("Robin", "Brown", 2300),
new ("Joe", "Draker", 1190),
new ("Janet", "Doe", 980),
];
users.Sort((u1, u2) => u1.LastName.CompareTo(u2.LastName));
users.ForEach(Console.WriteLine);
record User(string FirstName, string LastName, int Salary);
我们有一个用户对象列表。 用户具有三个属性:名字、姓氏和薪水。 我们按用户的姓氏对列表进行排序。
users.Sort((u1, u2) => u1.LastName.CompareTo(u2.LastName));
在 lambda 表达式中,我们比较两个元素的 LastName 属性。
$ dotnet run
User { FirstName = Robin, LastName = Brown, Salary = 2300 }
User { FirstName = John, LastName = Doe, Salary = 1230 }
User { FirstName = John, LastName = Doe, Salary = 1230 }
User { FirstName = Janet, LastName = Doe, Salary = 980 }
User { FirstName = Joe, LastName = Draker, Salary = 1190 }
User { FirstName = Lucy, LastName = Novak, Salary = 670 }
User { FirstName = Ben, LastName = Walter, Salary = 2050 }
接下来,我们按用户的薪水进行排序。
List<User> users = [
new ("John", "Doe", 1230),
new ("John", "Doe", 1230),
new ("Lucy", "Novak", 670),
new ("Ben", "Walter", 2050),
new ("Robin", "Brown", 2300),
new ("Joe", "Draker", 1190),
new ("Janet", "Doe", 980),
];
Console.WriteLine("sort ascending by salary");
var enum1 = from user in users
orderby user.Salary
select user;
foreach (var e in enum1)
{
Console.WriteLine(e);
}
Console.WriteLine("--------------------------");
Console.WriteLine("sort descending by salary");
var enum2 = from user in users
orderby user.Salary descending
select user;
foreach (var e in enum2)
{
Console.WriteLine(e);
}
record User(string FirstName, string LastName, int Salary);
该示例按用户的薪水对用户对象列表进行排序。 它使用 LINQ 查询语法。
$ dotnet run
sort ascending by salary
User { FirstName = Lucy, LastName = Novak, Salary = 670 }
User { FirstName = Janet, LastName = Doe, Salary = 980 }
User { FirstName = Joe, LastName = Draker, Salary = 1190 }
User { FirstName = John, LastName = Doe, Salary = 1230 }
User { FirstName = Ben, LastName = Walter, Salary = 2050 }
User { FirstName = Robin, LastName = Brown, Salary = 2300 }
--------------------------
sort descending by salary
User { FirstName = Robin, LastName = Brown, Salary = 2300 }
User { FirstName = Ben, LastName = Walter, Salary = 2050 }
User { FirstName = John, LastName = Doe, Salary = 1230 }
User { FirstName = Joe, LastName = Draker, Salary = 1190 }
User { FirstName = Janet, LastName = Doe, Salary = 980 }
User { FirstName = Lucy, LastName = Novak, Salary = 670 }
C# List 排序 DateTime
在以下示例中,我们按用户的生日对用户列表进行排序。
List<User> users = [
new ("John", "Doe", new DateTime(1983, 9, 4)),
new ("Lucy", "Novak", new DateTime(1978, 11, 18)),
new ("Ben", "Walter", new DateTime(1998, 12, 1)),
new ("Robin", "Brown", new DateTime(2001, 2, 14)),
new ("Joe", "Draker", new DateTime(1980, 1, 10)),
new ("Janet", "Doe", new DateTime(1967, 8, 23)),
];
Console.WriteLine("sort ascending by birthday");
users.Sort((u1, u2) => DateTime.Compare(u1.Birthday, u2.Birthday));
users.ForEach(Console.WriteLine);
Console.WriteLine("--------------------------");
Console.WriteLine("sort descending by birthday");
var enum1 = users.OrderByDescending(e => e.Birthday);
foreach (var u in enum1)
{
Console.WriteLine(u);
}
Console.WriteLine("--------------------------");
Console.WriteLine("sort ascending by birthday");
var enum2 = from user in users
orderby user.Birthday
select user;
foreach (var u in enum2)
{
Console.WriteLine(u);
}
record User(string FirstName, string LastName, DateTime Birthday);
在该示例中,我们使用 Sort 方法,以及 LINQ 查询语法和方法语法按用户的生日对用户对象列表进行排序。
$ dotnet run
sort ascending by birthday
User { FirstName = Janet, LastName = Doe, Birthday = 8/23/1967 12:00:00 AM }
User { FirstName = Lucy, LastName = Novak, Birthday = 11/18/1978 12:00:00 AM }
User { FirstName = Joe, LastName = Draker, Birthday = 1/10/1980 12:00:00 AM }
User { FirstName = John, LastName = Doe, Birthday = 9/4/1983 12:00:00 AM }
User { FirstName = Ben, LastName = Walter, Birthday = 12/1/1998 12:00:00 AM }
User { FirstName = Robin, LastName = Brown, Birthday = 2/14/2001 12:00:00 AM }
--------------------------
sort descending by birthday
User { FirstName = Robin, LastName = Brown, Birthday = 2/14/2001 12:00:00 AM }
User { FirstName = Ben, LastName = Walter, Birthday = 12/1/1998 12:00:00 AM }
User { FirstName = John, LastName = Doe, Birthday = 9/4/1983 12:00:00 AM }
User { FirstName = Joe, LastName = Draker, Birthday = 1/10/1980 12:00:00 AM }
User { FirstName = Lucy, LastName = Novak, Birthday = 11/18/1978 12:00:00 AM }
User { FirstName = Janet, LastName = Doe, Birthday = 8/23/1967 12:00:00 AM }
--------------------------
sort ascending by birthday
User { FirstName = Janet, LastName = Doe, Birthday = 8/23/1967 12:00:00 AM }
User { FirstName = Lucy, LastName = Novak, Birthday = 11/18/1978 12:00:00 AM }
User { FirstName = Joe, LastName = Draker, Birthday = 1/10/1980 12:00:00 AM }
User { FirstName = John, LastName = Doe, Birthday = 9/4/1983 12:00:00 AM }
User { FirstName = Ben, LastName = Walter, Birthday = 12/1/1998 12:00:00 AM }
User { FirstName = Robin, LastName = Brown, Birthday = 2/14/2001 12:00:00 AM }
C# List 按多个字段排序对象
以下示例按多个字段对用户对象进行排序。
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),
];
users.Sort((u1, u2) =>
{
int result = u1.LastName.CompareTo(u2.LastName);
return result == 0 ? u1.Salary.CompareTo(u2.Salary) : result;
});
Console.WriteLine("sort ascending by last name and salary");
foreach (var user in users)
{
Console.WriteLine(user);
}
record User(string FirstName, string LastName, int Salary);
在该示例中,我们首先按姓氏然后按薪水对用户进行排序。
users.Sort((u1, u2) =>
{
int result = u1.LastName.CompareTo(u2.LastName);
return result == 0 ? u1.Salary.CompareTo(u2.Salary) : result;
});
首先,比较用户的 LastName 属性。 如果比较返回 0,即他们的姓氏相等,我们比较他们的薪水。
$ 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 }
下一个示例使用 LINQ 方法按多个字段排序。
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 enum1 = users.OrderBy(u => u.LastName).ThenBy(u => u.Salary);
foreach (var user in enum1)
{
Console.WriteLine(user);
}
record User(string FirstName, string LastName, int Salary);
用户使用 OrderBy 和 ThenBy 方法进行排序。
C# List 按评级排序
假设我们有一个无法按字母顺序排序的评级系统。 例如,评级可以具有诸如 C、C+、C- 之类的值。一种解决方案是使用枚举。
List<Product> products = [
new() { Name = "Product A", ProdRat = Rating.A },
new() { Name = "Product B", ProdRat = Rating.AMinus },
new() { Name = "Product C", ProdRat = Rating.B },
new() { Name = "Product D", ProdRat = Rating.APlus },
new() { Name = "Product E", ProdRat = Rating.D },
new() { Name = "Product F", ProdRat = Rating.C },
new() { Name = "Product G", ProdRat = Rating.CMinus },
new() { Name = "Product G", ProdRat = Rating.CPlus },
];
Console.WriteLine("sorted by rating ascending");
products.Sort((p1, p2) => p1.ProdRat.CompareTo(p2.ProdRat));
foreach (var product in products)
{
Console.WriteLine(product);
}
Console.WriteLine("---------------------");
Console.WriteLine("sorted by rating descending");
products.Sort((p1, p2) => p2.ProdRat.CompareTo(p1.ProdRat));
foreach (var product in products)
{
Console.WriteLine(product);
}
enum Rating
{
D,
DPlus,
CMinus,
C,
CPlus,
B,
BPlus,
BMinus,
AMinus,
A,
APlus
}
class Product
{
private readonly Dictionary<Rating, string> ratings = new()
{
{Rating.APlus, "A+"}, {Rating.A, "A"}, {Rating.AMinus, "A-"},
{Rating.BPlus, "B+"}, {Rating.B, "B"}, {Rating.BMinus, "B-"},
{Rating.CPlus, "C+"}, {Rating.C, "C"}, {Rating.CMinus, "C-"},
{Rating.DPlus, "D+"}, {Rating.D, "D"}
};
public string? Name { get; init; }
public Rating ProdRat { get; init; }
public override string ToString()
{
return $"{Name} has rating {ratings[ProdRat]}";
}
}
在该示例中,我们按产品的评级对产品进行排序。
products.Sort((p1, p2) => p1.ProdRat.CompareTo(p2.ProdRat));
在 lambda 表达式中,我们使用 CompareTo 比较产品排名枚举。
enum Rating
{
D,
DPlus,
CMinus,
C,
CPlus,
B,
BPlus,
BMinus,
AMinus,
A,
APlus
}
我们有一个评级枚举。 在内部,这些值被赋予整数,其中 Rating.D 具有最低值,而 Rating.APlus 具有最高值。
private readonly Dictionary<Rating, string> ratings = new()
{
{Rating.APlus, "A+"}, {Rating.A, "A"}, {Rating.AMinus, "A-"},
{Rating.BPlus, "B+"}, {Rating.B, "B"}, {Rating.BMinus, "B-"},
{Rating.CPlus, "C+"}, {Rating.C, "C"}, {Rating.CMinus, "C-"},
{Rating.DPlus, "D+"}, {Rating.D, "D"}
};
在此字典中,我们将字符串表示形式分配给我们的排名枚举。
$ dotnet run sorted by rating ascending Product E has rating D Product G has rating C- Product F has rating C Product G has rating C+ Product C has rating B Product B has rating A- Product A has rating A Product D has rating A+ --------------------- sorted by rating descending Product D has rating A+ Product A has rating A Product B has rating A- Product C has rating B Product G has rating C+ Product F has rating C Product G has rating C- Product E has rating D
产品按其评级升序和降序排序。
C# List 排序卡片
在下一个示例中,我们对卡片进行排序。 Card 对象实现 IComparable 接口。 该接口用于可以自然排序对象的情况。
在扑克和类似的纸牌游戏中,卡牌的值由其等级决定。 如果需要,由其花色决定。 在扑克中只有一种可能的纸牌排序方式; 因此,我们可以使用 IComparable 接口。
List<Card> cards =
[
new (Rank.King, Suit.Diamonds),
new (Rank.Five, Suit.Hearts),
new (Rank.Ace, Suit.Clubs),
new (Rank.Nine, Suit.Spades),
new (Rank.Jack, Suit.Spades),
new (Rank.Jack, Suit.Diamonds)
];
cards.Sort();
foreach (var card in cards)
{
Console.WriteLine(card);
}
enum Rank
{
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King,
Ace
}
enum Suit
{
Clubs,
Diamonds,
Hearts,
Spades
}
class Card(Rank rank, Suit suit) : IComparable<Card>
{
private Rank Rank { get; set; } = rank;
private Suit Suit { get; set; } = suit;
public int CompareTo(Card? other)
{
if (other == null) return 1;
var index = Rank.CompareTo(other.Rank);
if (index == 0) index = Suit.CompareTo(other.Suit);
return index;
}
public override string ToString()
{
return $"{Rank} of {Suit}";
}
}
在该示例中,我们对卡片进行排序。
List<Card> cards =
[
new (Rank.King, Suit.Diamonds),
new (Rank.Five, Suit.Hearts),
new (Rank.Ace, Suit.Clubs),
new (Rank.Nine, Suit.Spades),
new (Rank.Jack, Suit.Spades),
new (Rank.Jack, Suit.Diamonds)
];
我们有一个想要排序的六张卡片的列表。
class Card : IComparable<Card>
Card 实现了 IComparable 接口。 这迫使我们实现它的 CompareTo 方法。
public int CompareTo(Card? other)
{
if (other == null) return 1;
var index = Rank.CompareTo(other.Rank);
if (index == 0) index = Suit.CompareTo(other.Suit);
return index;
}
在 CompareTo 方法中,我们首先比较卡片的等级。 如果等级相同,我们比较花色。
cards.Sort();
在没有任何参数的情况下,Sort 方法调用内置的 CompareTo 来对数据进行排序。
$ dotnet run Five of Hearts Nine of Spades Jack of Diamonds Jack of Spades King of Diamonds Ace of Clubs
我们有两张相同等级的卡牌 - Jacks。 黑桃杰克比方块杰克等级更高。
来源
在本文中,我们在 C# 语言中对列表元素进行了排序。
作者
列出所有 C# 教程。