如何根据项的整数值对List进行排序
清单就像
"1"
"5"
"3"
"6"
"11"
"9"
"NUM1"
"NUM0"
Run Code Online (Sandbox Code Playgroud)
结果应该是这样的
"1"
"3"
"5"
"6"
"9"
"11"
"NUM0"
"NUM1"
Run Code Online (Sandbox Code Playgroud)
有什么想法使用LINQ或Lambda表达式吗?
提前致谢
Mar*_*ell 16
怎么样:
list.Sort((x, y) =>
{
int ix, iy;
return int.TryParse(x, out ix) && int.TryParse(y, out iy)
? ix.CompareTo(iy) : string.Compare(x, y);
});
Run Code Online (Sandbox Code Playgroud)
ang*_*son 16
这被称为"自然排序顺序",通常用于对您拥有的项目进行排序,如文件名等.
这是一个天真的(在某种意义上,它可能存在大量的unicode问题)实现似乎可以解决这个问题:
您可以将以下代码复制到LINQPad中以执行它并进行测试.
基本上比较算法将确定数字字符串内,并通过填充最短的一个具有前导零处理这些,所以比如两个字符串"Test123Abc",并"Test7X"应就好像它们是进行比较"Test123Abc"和"Test007X",这应该产生你想要什么.
然而,当我说"天真"时,我的意思是我可能在这里有很多真正的unicode问题,比如处理变音符号和多码点字符.如果有人能够提供更好的实施,我很乐意看到它.
笔记:
码:
void Main()
{
List<string> input = new List<string>
{
"1", "5", "3", "6", "11", "9", "A1", "A0"
};
var output = input.NaturalSort();
output.Dump();
}
public static class Extensions
{
public static IEnumerable<string> NaturalSort(
this IEnumerable<string> collection)
{
return NaturalSort(collection, CultureInfo.CurrentCulture);
}
public static IEnumerable<string> NaturalSort(
this IEnumerable<string> collection, CultureInfo cultureInfo)
{
return collection.OrderBy(s => s, new NaturalComparer(cultureInfo));
}
private class NaturalComparer : IComparer<string>
{
private readonly CultureInfo _CultureInfo;
public NaturalComparer(CultureInfo cultureInfo)
{
_CultureInfo = cultureInfo;
}
public int Compare(string x, string y)
{
// simple cases
if (x == y) // also handles null
return 0;
if (x == null)
return -1;
if (y == null)
return +1;
int ix = 0;
int iy = 0;
while (ix < x.Length && iy < y.Length)
{
if (Char.IsDigit(x[ix]) && Char.IsDigit(y[iy]))
{
// We found numbers, so grab both numbers
int ix1 = ix++;
int iy1 = iy++;
while (ix < x.Length && Char.IsDigit(x[ix]))
ix++;
while (iy < y.Length && Char.IsDigit(y[iy]))
iy++;
string numberFromX = x.Substring(ix1, ix - ix1);
string numberFromY = y.Substring(iy1, iy - iy1);
// Pad them with 0's to have the same length
int maxLength = Math.Max(
numberFromX.Length,
numberFromY.Length);
numberFromX = numberFromX.PadLeft(maxLength, '0');
numberFromY = numberFromY.PadLeft(maxLength, '0');
int comparison = _CultureInfo
.CompareInfo.Compare(numberFromX, numberFromY);
if (comparison != 0)
return comparison;
}
else
{
int comparison = _CultureInfo
.CompareInfo.Compare(x, ix, 1, y, iy, 1);
if (comparison != 0)
return comparison;
ix++;
iy++;
}
}
// we should not be here with no parts left, they're equal
Debug.Assert(ix < x.Length || iy < y.Length);
// we still got parts of x left, y comes first
if (ix < x.Length)
return +1;
// we still got parts of y left, x comes first
return -1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12624 次 |
| 最近记录: |