如果我有一些字符串列表包含所有数字和破折号,他们将按升序排序:
s = s.OrderBy(t => t).ToList();
Run Code Online (Sandbox Code Playgroud)
66-0616280-000
66-0616280-100
66-06162801000
66-06162801040
这是预期的.
但是,如果字符串包含字母,则排序有些出乎意料.例如,这里是相同的字符串列表,尾随A代替0,是的,它是排序的:
66-0616280-00A
66-0616280100A
66-0616280104A
66-0616280-10A
我原以为他们会这样排序:
66-0616280-00A
66-0616280-10A
66-0616280100A
66-0616280104A
当字符串包含字母时,为什么排序在字符串上的行为不同?
提前致谢.
Jon*_*eet 12
这是因为默认StringComparer是文化敏感的.据我所知,使用当前文化的Comparer<string>.Default代表string.CompareTo(string):
此方法使用当前文化执行单词(区分大小写和文化敏感)比较.有关word,string和ordinal排序的更多信息,请参阅
System.Globalization.CompareOptions.
然后页面CompareOptions包括:
.NET Framework使用三种不同的排序方式:单词排序,字符串排序和顺序排序.单词排序执行文化敏感的字符串比较.某些非字母数字字符可能会分配特殊权重.例如,连字符(" - ")可能具有非常小的权重,因此"coop"和"co-op"在排序列表中彼此相邻.字符串排序类似于单词排序,除了没有特殊情况.因此,所有非字母数字符号都在所有字母数字字符之前.序数排序根据字符串的每个元素的Unicode值比较字符串.
("小重量"与安德烈答案中引用的"忽略"并不完全相同,但效果在这里类似.)
如果您指定StringComparer.Ordinal,则会得到以下结果:
66-0616280-00A
66-0616280-10A
66-0616280100A
66-0616280104A
Run Code Online (Sandbox Code Playgroud)
将其指定为第二个参数OrderBy:
s = s.OrderBy(t => t, StringComparer.Ordinal).ToList();
Run Code Online (Sandbox Code Playgroud)
你可以在这里看到差异:
Console.WriteLine(Comparer<string>.Default.Compare
("66-0616280104A", "66-0616280-10A"));
Console.WriteLine(StringComparer.Ordinal.Compare
("66-0616280104A", "66-0616280-10A"));
Run Code Online (Sandbox Code Playgroud)
以下是MSDN的评论:
字符集包括可忽略的字符.Compare(String,String)方法在执行区分文化的比较时不考虑这些字符.例如,如果在.NET Framework 4或更高版本上运行以下代码,则对"动物"与"动画"(使用软连字符或U + 00AD)进行区分文化比较表示两个字符串是当量.
所以看起来你正在经历这种可忽略的角色案例.如果我们假设-符号的权重非常小,则排序结果如下所示.
第一种情况:
660616280000
660616280100
6606162801000
6606162801040
Run Code Online (Sandbox Code Playgroud)
第二种情况:
66061628000A
660616280100A
660616280104A
66061628010A
Run Code Online (Sandbox Code Playgroud)
这是有道理的
| 归档时间: |
|
| 查看次数: |
1481 次 |
| 最近记录: |