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"之前。
我怀疑在最后一种情况下,由于特定于区域性的设置(可能是"破折号"而不是第一个字符串中的"减号"(,"-"以不同的方式处理。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