C# 中的字符串排序问题

本文关键字:排序 问题 字符串 | 更新日期: 2023-09-27 18:25:04

我有这样的列表

    List<string> items = new List<string>();
    items.Add("-");
    items.Add(".");
    items.Add("a-");
    items.Add("a.");
    items.Add("a-a");
    items.Add("a.a");
    items.Sort();
    string output = string.Empty;
    foreach (string s in items)
    {
        output += s + Environment.NewLine;
    }
MessageBox.Show(output);

输出返回为

-
.
a-
a.
a.a
a-a

正如我所期望的结果一样

-
.
a-
a.
a-a
a.a
知道为什么"a-a">

不在"a.a"之前,而"a-"在"a"之前。

C# 中的字符串排序问题

我怀疑在最后一种情况下,由于特定于区域性的设置(可能是"破折号"而不是第一个字符串中的"减号"(,"-"以不同的方式处理。MSDN 对此发出警告:

比较使用当前区域性来获取特定于区域性 大小写规则和字母顺序等信息 单个字符。例如,区域性可以指定 某些字符组合被视为单个字符, 或以特定方式比较大写和小写字符, 或者字符的排序顺序取决于字符 在它之前或之后。

另请参阅此 MSDN 页:

.NET Framework 使用三种不同的排序方式:单词排序、 字符串排序和序号排序。单词排序执行区分区域性 字符串的比较。某些非字母数字字符可能具有 分配给他们的特殊权重;例如,连字符 ("-"( 可能 为其分配非常小的权重,以便"coop"和"co-op" 在排序列表中彼此并排显示。字符串排序类似于 单词排序,除了没有特殊情况;因此,所有 非字母数字符号位于所有字母数字字符之前。 序号排序根据每个字符串的 Unicode 值比较字符串 元素。

因此,连字符在默认排序模式下得到了特殊处理,以使单词排序更加"自然"。

如果您专门打开它,则可以获得"正常"序号排序:

     Console.WriteLine(string.Compare("a.", "a-"));                  //1
     Console.WriteLine(string.Compare("a.a", "a-a"));                //-1
     Console.WriteLine(string.Compare("a.", "a-", StringComparison.Ordinal));    //1
     Console.WriteLine(string.Compare("a.a", "a-a", StringComparison.Ordinal));  //1

要使用序号比较对原始集合进行排序,请使用:

     items.Sort(StringComparer.Ordinal);

如果您希望字符串排序基于实际字节值,而不是当前区域性定义的规则,则可以按序号排序:

items.Sort(StringComparer.Ordinal);

这将使结果在所有文化中保持一致(但它会产生"14"在"9"之前的不直观排序,这可能是也可能不是您要查找的(。

List<>类的Sort方法依赖于.NET Framework的默认string比较器,它实际上是Thread的当前CultureInfo的实例。

CultureInfo指定了字符的字母顺序,似乎默认的顺序与您期望的顺序不同。

排序时,您可以指定一个特定的CultureInfo,一个您知道将符合您的分类要求,样本(德国文化(:

var sortCulture = new CultureInfo("de-DE");
items.Sort(sortCulture);

更多信息可以在这里找到:

http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspxhttp://msdn.microsoft.com/de-de/library/system.stringcomparer.aspx