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

时间:2013-08-29 12:45:28

标签: c# list sorting criteria collation

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

我做了什么:

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字母之间。

3 个答案:

答案 0 :(得分: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 :(得分:1)

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

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

这会将_Students置于所有其他*students之前......此时按ThenBy(s => s.Length)排序将毫无用处。

如果您已经拥有以空格开头的字符串,那么这显然会产生一些混乱。如果您有,请用另一个角色更改空间。

答案 2 :(得分:0)

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

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

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