字母顺序从左到右不比较?

时间:2014-06-25 12:15:25

标签: c# .net string sorting .net-4.0

我认为.NET字符串按字母顺序进行比较,并且从左到右进行比较。

string[] strings = { "-1", "1", "1Foo", "-1Foo" };
Array.Sort(strings);
Console.WriteLine(string.Join(",", strings));

我期待这一点(或者首先是开头的减号):

1,1Foo,-1,-1Foo

但结果是:

1,-1,1Foo,-1Foo

它似乎是一种混合,要么忽略减号,要么比较多个字符,即使第一个字符已经不同。

修改:我现在已经测试OrdinalIgnoreCase了,我得到了预期的订单:

Array.Sort(strings, StringComparer.OrdinalIgnoreCase);

但即使我使用InvariantCultureIgnoreCase,我也会收到意外的订单。

2 个答案:

答案 0 :(得分:2)

String.CompareTo方法文档中有一个小注释:

  

来电者注意事项:

     

字符集包括可忽略的字符。该   CompareTo(String)方法不考虑这样的字符   进行文化敏感的比较。例如,如果以下   代码在.NET Framework 4或更高版本上运行,比较“动物”   用“ani-mal”(使用软连字符,或U + 00AD)表示两者   字符串是等价的。

然后稍后陈述:

  

要识别字符串比较中的可忽略字符,请调用   CompareOrdinal(String,String)方法。

这两个陈述似乎与您所看到的结果一致。

答案 1 :(得分:2)

Jon Skeet拯救here

具体做法是:

  

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

但添加StringComparer.Ordinal使其行为符合您的要求:

string[] strings = { "-1", "1", "10", "-10", "a", "ba","-a" };      
Array.Sort(strings,StringComparer.Ordinal );
Console.WriteLine(string.Join(",", strings));
// prints: -1,-10,-a,1,10,a,ba

修改
关于Ordinal,引自MSDN CompareOptions Enumeration

  

Ordinal 表示字符串比较必须使用连续   Unicode UTF-16编码的字符串值(代码单位的代码单位)   比较),导致快速比较,但一个   文化不敏感。以代码单元XXXX16开头的字符串出现   在以YYYY16开头的字符串之前,如果XXXX16小于YYYY16。   此值不能与其他CompareOptions值组合使用   必须单独使用。

如果你想要2个字符串的序数,你似乎也有String.CompareOrdinal

这是另一个感兴趣的注意事项:

  

如果可能,应用程序应使用字符串比较方法   接受CompareOptions值以指定比较类型   预期。作为一般规则,最佳服务是面向用户的比较   通过使用语言选项(使用当前的文化),同时   安全性比较应指定Ordinal或OrdinalIgnoreCase。

我猜我们人类在处理字符串时会期望序数:)