列表排序,其中包含以下划线开头的字符串

问题描述 投票:3回答:3

所以这就是我得到的:我有一个包含这些字符串的列表:“学生”,“学生”,“学生”,“学生”和“_学生”。

我做了什么:

List<string> sort = new List<string>() { "student", "Students", "students", "Student","_Students" };
List<string> custsort = sort.OrderBy(st => st[0]).ThenBy(s => s.Length)
                                                             .ToList();

但这给了我这样的:

Student
Students
_Students
student
students

而我想要的是:

_Students
Student
Students
student
students

我无法弄清楚如何对它们进行排序,因为该死的下划线位于ASCII表中的upperCase和lowerCase字母之间。

c# list sorting criteria collation
3个回答
4
投票

您可以使用正则表达式来确定第一个字符是否为字母并对其应用权重。

int GetWeight(char c)
{
    return Regex.IsMatch(c.ToString(), @"[a-zA-Z]") ? c : 0;
}

List<string> sort = new List<string>() { "student", "Students", "students", "Student","_Students" };
List<string> custsort =
    sort.OrderBy(st => GetWeight(st[0]))
        .ThenBy(s => s.Length)
        .ToList();

这样,如果您需要任何其他特殊规则,您可以修改GetWeight函数,您的Linq将不受影响。


1
投票

例如,您可以将_视为(space),如下所示:

List<string> custsort = sort.OrderBy(st => st.Replace('_', ' '))
                            .ToList();

这将把_Students放在所有其他*students之前......此时按ThenBy(s => s.Length)排序将是无用的。

如果你已经有一个以空格开头的字符串,这显然会造成一点点混乱。如果您有,请使用其他角色更改空间。


0
投票

您可以使用仅返回true或false的排序条件 - 任何false项都会在任何真项之前放置。在下面的代码中,我添加了第一个OrderBy,它首先放置以下划线开头的项目。

List<string> custsort = sort.OrderBy(st => st[0] != '_')
                        .ThenBy(st => st[0])
                        .ThenBy(s => s.Length)
                        .ToList();

查询的其余部分使用与之前相同的规则 - 按第一个字符排序,然后按每个字符串的长度排序。

© www.soinside.com 2019 - 2024. All rights reserved.