C#中的字符串排序问题

时间:2012-02-20 00:58:33

标签: c# string sorting cultureinfo

我有这样的列表

    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

知道为什么&#34; a-a&#34;是不是来之前&#34; a.a&#34; as&#34; a - &#34;来自&#34; a。&#34;

3 个答案:

答案 0 :(得分:17)

我怀疑在最后一种情况下,由于特定于文化的设置(可能是“破折号”而不是第一个字符串中的“减号”),“ - ”会以不同的方式处理。关于此事MSDN warns

  

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

另见this MSDN page

  

.NET Framework使用三种不同的排序方式:单词排序,   字符串排序和序数排序。单词排序执行文化敏感   字符串的比较。某些非字母数字字符可能有   分配给他们的特殊重量;例如,连字符(“ - ”)可能   分配给它的重量非常小,以便“合作”和“合作”   在排序列表中彼此相邻。字符串排序类似于   单词排序,除了没有特殊情况;所以,一切   非字母数字符号位于所有字母数字字符之前。   序数排序根据每个字符串的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);

答案 1 :(得分:4)

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

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

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

CultureInfo

更多信息可以在这里找到:
http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx
http://msdn.microsoft.com/de-de/library/system.stringcomparer.aspx

答案 2 :(得分:4)

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

items.Sort(StringComparer.Ordinal);

这将使结果在所有文化中保持一致(但是它会在“9”之前产生非直观的“14”排序,这可能是也可能不是你想要的)。