一尘不染

使用LINQ的字母数字排序

c#

我有一个string[]其中每个元素都以某个数字结尾的值。

string[] partNumbers = new string[] 
{ 
    "ABC10", "ABC1","ABC2", "ABC11","ABC10", "AB1", "AB2", "Ab11" 
};

我正在尝试使用以下方式对上面的数组进行排序,LINQ但没有得到预期的结果。

var result = partNumbers.OrderBy(x => x);

实际结果:

AB1
Ab11
AB2
ABC1
ABC10
ABC10
ABC11
ABC2

预期结果

AB1
AB2
AB11
..


阅读 250

收藏
2020-05-19

共1个答案

一尘不染

这是因为字符串的默认排序是标准字母数字字典(词典)排序,并且ABC11会先于ABC2,因为排序始终是从左到右进行的。

要获得所需的内容,需要在order by子句中填充数字部分,例如:

 var result = partNumbers.OrderBy(x => PadNumbers(x));

在那里PadNumbers可以定义为:

public static string PadNumbers(string input)
{
    return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
}

这会将输入字符串中出现的任何数字(或多个数字)填充零,这样可以OrderBy看到:

ABC0000000010
ABC0000000001
...
AB0000000011

填充仅发生在用于比较的键上。原始字符串(不带填充)保留在结果中。

请注意,此方法假定输入中数字的最大位数。

2020-05-19