我有一个文件名数组,我想按数字样式排序,请给我一个解决方案。
例1:
原始阵列:[name99.txt, name98.txt, name100.txt]
排序数组:[name98.txt, name99.txt, name100.txt]
(使用字符串排序,排序结果为[name100.txt, name98.txt, name99.txt]
)
例2:
原始阵列:[a99.txt, b98.txt, b100.txt]
排序数组:[a99.txt, b98.txt, b100.txt]
(使用字符串排序,排序结果为[a99.txt, b100.txt, b99.txt]
)
答案 0 :(得分:8)
string[] ar = new string[] { "name99.txt", "name98.txt", "name100.txt" };
Array.Sort(ar, (a, b) => int.Parse(Regex.Replace(a, "[^0-9]", "")) - int.Parse(Regex.Replace(b, "[^0-9]", "")));
foreach (var a in ar)
Console.WriteLine(a);
以上假设您的文件始终称为name###.txt
。对于真正的数字排序,请使用以下更复杂的版本:
public static void NumericalSort(string[] ar)
{
Regex rgx = new Regex("([^0-9]*)([0-9]+)");
Array.Sort(ar, (a, b) =>
{
var ma = rgx.Matches(a);
var mb = rgx.Matches(b);
for (int i = 0; i < ma.Count; ++i)
{
int ret = ma[i].Groups[1].Value.CompareTo(mb[i].Groups[1].Value);
if (ret != 0)
return ret;
ret = int.Parse(ma[i].Groups[2].Value) - int.Parse(mb[i].Groups[2].Value);
if (ret != 0)
return ret;
}
return 0;
});
}
static void Main(string[] args)
{
string[] ar = new string[] { "a99.txt", "b98.txt", "b100.txt" };
NumericalSort(ar);
foreach (var a in ar)
Console.WriteLine(a);
}
答案 1 :(得分:4)
可能有一种管理方式可以做到这一点,但我可能只是P /调用StrCmpLogicalW
。
[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
static extern int StrCmpLogicalW(String x, String y);
如果您使用此函数,而不是滚动自己的比较函数,您将获得与Explorer和使用逻辑比较的其他系统组件相同的行为。
但请注意,这在WinAPI无法访问的环境(例如Windows Phone,Mono或Silverlight)might work differently on different systems中不起作用,并且应该使用注释进行修饰,以便代码的未来维护者知道原因P / Invoke用于排序。
答案 2 :(得分:1)
可在此处找到一个解决方案:Alphanumeric Sorting
答案 3 :(得分:0)
当数字块的长度不超过 9 位时,我的方法很好:
private string[] NumericalSort(IEnumerable<string> list)
{
var ar = list.ToArray();
Array.Sort(ar, (a, b) =>
{
var aa = Regex.Replace(a, @"\d+", m => m.Value.PadLeft(9, '0'));
var bb = Regex.Replace(b, @"\d+", m => m.Value.PadLeft(9, '0'));
return string.Compare(aa, bb);
});
return ar;
}