C#列表排序教程展示了如何使用C#语言对列表元素进行排序。
排序
在计算机科学中,排序是按有序顺序排列元素。多年来,开发了多种算法来对数据进行排序,包括归并排序、快速排序、选择排序或冒泡排序。(排序的另一个含义是归类,将具有相似属性的元素分组。)
与排序相反,以随机或无意义的顺序重新排列一系列元素,称为洗牌。
数据可以按字母顺序或数字顺序排序。排序键指定用于执行排序的标准。可以通过多个键对对象进行排序。例如,在对用户进行排序时,可以将用户的姓名作为主排序键,将职业作为次排序键。
排序顺序
标准顺序称为升序: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#列表排序方法
Sort
方法对列表中的元素或部分元素进行排序。
该方法有四个重载:
- Sort(Comparison)-使用指定的Comparison对整个List中的元素进行排序。
- Sort(Int32,Int32,IComparer)-使用指定的比较器对List中的元素范围内的元素进行排序。
- Sort()-使用默认比较器对整个List中的元素进行排序。
- Sort(IComparer)-使用指定的比较器对整个List中的元素进行排序。
比较法
排序算法已经内置到该语言的标准库中。如果数据不是自然排序的,我们需要提供一个比较方法(类方法或lambda表达式)来告诉底层排序算法如何对数据进行排序。对哪些属性进行排序以及以何种方式进行排序。
public int CompareTo(Card other) { var index = Rank.CompareTo(other.Rank); if (index == 0) index = Suit.CompareTo(other.Suit); return index; }
例如,这个比较类方法告诉对象按Rank
排序,如果排名相同,则按Suit
排序。我们总是比较两个元素;在我们的例子中,有两个卡片对象。如果元素相等,则比较方法返回0,如果第一个元素小于第二个元素,则返回-1,如果第一个元素大于第二个元素,则返回1。
通常,我们的比较函数会调用其他比较函数;在我们的例子中,Rank
和Suit
是枚举,我们通过内置的CompareTo
方法比较它们。
C#列表排序整数
以下示例对整数进行排序。
var nums = new List<int> { 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中,我们可以在查询语法或方法语法之间进行选择。
var nums = new List<int> { 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#列表排序字符串
与整数一样,字符串默认按字母顺序Sort
排序,无需任何额外操作。
var words = new List<string> {"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#列表排序重音字符串
为了对重音字符串进行排序,我们需要提供适当的CultureInfo
。
using System.Globalization; Console.OutputEncoding = System.Text.Encoding.UTF8; CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK"); var words = new List<string> { "Ä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#列表按字符串长度排序
以下示例按单词的长度对单词列表进行排序。
var words = new List<string> {"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执行相同的操作。
var words = new List<string> {"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#列表按姓氏排序
当我们想按姓氏对名字进行排序时,假设整个名字是一个字符串,我们需要提供一个自定义的比较方法。
var names = new List<string> {"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解决方案。
var names = new List<string> {"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#列表排序不区分大小写
要以不区分大小写的方式比较字符串,我们可以使用内置的StringComparer.OrdinalIgnoreCase
。
var words = new List<string> { "world", "War", "abbot", "Caesar", "castle", "sky", "den", "forest", "ocean", "water", "falcon", "owl", "rain", "Earth" }; words.Sort(StringComparer.OrdinalIgnoreCase); words.ForEach(w => Console.WriteLine(w));
该示例以不区分大小写的顺序对单词列表进行排序。
$ dotnet run abbot Caesar castle den Earth falcon forest ocean owl rain sky War water world
C#列表排序与比较
Comparison
委托表示比较同一类型的两个对象的方法。
var employees = new List<(string, int)> { ("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表达式。
var employees = new List<(string, int)> { ("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)
使用IComparable对C#列表进行排序
IComparable
接口定义了一个通用的特定于类型的比较方法,值类型或类实现该方法以对其实例进行排序或排序。
IComparable
接口最适用于排序明显的较小、紧凑的类型。
var employees = new List<Employee> { new Employee("John Doe", 1230), new Employee("Adam Novak", 670), new Employee("Robin Brown", 2300), new Employee("Rowan Cruise", 990), new Employee("Joe Draker", 1190), new Employee("Janet Doe", 980), new Employee("Lucy Smith", 980), new Employee("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) { return other.Salary.CompareTo(this.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 }
使用IComparer对C#列表进行排序
IComparer
接口定义了一个比较方法,值类型或类实现该方法以对其实例进行排序或排序。
使用IComparer
我们有更多的灵活性;我们可以在不触及类型本身的情况下定义多个比较器或更新现有的比较器。此外,它的设计更简洁,因为我们将排序实现与类型分开。
var employees = new List<(string, int)> { ("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#列表排序元组
以下示例对元组列表进行排序。
var data = new List<(string Name, int Grade)> { ("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#列表排序对象
在下面的示例中,我们对User
对象列表进行排序。
var users = new List<User> { 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(user => Console.WriteLine(user)); 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 }
接下来我们按薪水对用户进行排序。
var users = new List<User> { 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#列表排序日期时间
在下面的示例中,我们按生日对用户列表进行排序。
var users = new List<User> { 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(u => Console.WriteLine(u)); 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按多个字段对对象排序
以下示例按多个字段对用户对象进行排序。
var users = new List<User> { 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方法按多个字段排序。
var users = new List<User> { 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#列表按评分排序
图片显示我们有一个无法按字母顺序排序的评级系统。例如,评级可以有C、C+、C-等值。一种解决方案是使用枚举。
var products = new List<Product> { new Product() { Name = "Product A", ProdRat = Rating.A }, new Product() { Name = "Product B", ProdRat = Rating.AMinus }, new Product() { Name = "Product C", ProdRat = Rating.B }, new Product() { Name = "Product D", ProdRat = Rating.APlus }, new Product() { Name = "Product E", ProdRat = Rating.D }, new Product() { Name = "Product F", ProdRat = Rating.C }, new Product() { Name = "Product G", ProdRat = Rating.CMinus }, new Product() { 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 Dictionary<Rating, string> ratings = new Dictionary<Rating, string> { {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 $"{this.Name} has rating {this.ratings[this.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 Dictionary<Rating, string> ratings = new Dictionary<Rating, string> { {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#列表排序卡片
在下一个示例中,我们对卡片进行排序。Card
对象实现了IComparable
接口。该接口用于可能对对象进行自然排序的情况。
在扑克牌和类似的纸牌游戏中,纸牌价值由其等级决定。如果需要,由其诉讼。在扑克牌中只有一种可能的排序方式;因此,我们可以使用IComparable
接口。
var cards = new List<Card> { new Card(Rank.King, Suit.Diamonds), new Card(Rank.Five, Suit.Hearts), new Card(Rank.Ace, Suit.Clubs), new Card(Rank.Nine, Suit.Spades), new Card(Rank.Jack, Suit.Spades), new Card(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 : IComparable<Card> { private Rank Rank { get; set; } private Suit Suit { get; set; } public Card(Rank rank, Suit suit) { Rank = rank; Suit = suit; } public int CompareTo(Card other) { var index = Rank.CompareTo(other.Rank); if (index == 0) index = Suit.CompareTo(other.Suit); return index; } public override string ToString() { return $"{Rank} of {Suit}"; } }
在示例中,我们对卡片进行排序。
class Card : IComparable<Card>
Card
实现了IComparable
接口。这迫使我们实现它的CompareTo
方法。
public int CompareTo(Card other) { var index = Rank.CompareTo(other.Rank); if (index == 0) index = Suit.CompareTo(other.Suit); return index; }
在CompareTo
方法中,我们首先比较卡片的排名。如果等级相同,我们比较花色。
var cards = new List<Card> { new Card(Rank.King, Suit.Diamonds), new Card(Rank.Five, Suit.Hearts), new Card(Rank.Ace, Suit.Clubs), new Card(Rank.Nine, Suit.Spades), new Card(Rank.Jack, Suit.Spades), new Card(Rank.Jack, Suit.Diamonds) };
我们有一个包含六张要排序的卡片的列表。
cards.Sort();
在没有任何参数的情况下,Sort
方法调用内置的CompareTo
来对数据进行排序。
$ dotnet run Five of Hearts Nine of Spades Jack of Diamonds Jack of Spades King of Diamonds Ace of Clubs
我们有两张相同点数的牌——J。黑桃J的排名高于方片J。
在本文中,我们使用C#语言对列表元素进行了排序。
列出所有C#教程。