开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C# 排序列表

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。

通常,我们的比较函数会调用其他比较函数;在我们的例子中,RankSuit是枚举,我们通过内置的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);

用户使用OrderByThenBy方法进行排序。

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#教程。

未经允许不得转载:我爱分享网 » C# 排序列表

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏