我有一个String数组,其中包含
等文件名 1.Script_DBScript_03122014
我想对这个数组进行排序,所以我编写了以下代码:
Array.Sort(SQLScripts);
但是排序的数组产生如下:
1.Script_DBScript(otherdetails)_03122014
10.Script_DBScript(otherdetails)_03122014
11.Script_DBScript(otherdetails)_03122014
12.Script_DBScript(otherdetails)_03122014
...
2.Script_DBScript(otherdetails)_03122014
20.Script_DBScript(otherdetails)_03122014
21.Script_DBScript(otherdetails)_03122014
22.Script_DBScript(otherdetails)_03122014
... so on
如何以下列形式获取数组
1.Script_DBScript(otherdetails)_03122014
2.Script_DBScript(otherdetails)_03122014
3.Script_DBScript(otherdetails)_03122014
4.Script_DBScript(otherdetails)_03122014
5.Script_DBScript(otherdetails)_03122014
...
50.Script_DBScript(otherdetails)_03122014
编辑: 从目录中检索文件名的代码:
String[] SQLScripts = Directory.GetFiles(txtPath.Text, "*.sql");
答案 0 :(得分:3)
你得到的结果是非常常见的字符串排序。你需要的是数字(或数字)排序。
在这种情况下,您可能需要解析字符串,从第一个点的左侧提取数字,使用某些方法,如int.Parse("string containing a number")
,然后按整数进行排序。
我是这样做的,但是我不建议在不了解你的情况下复制粘贴我的代码:
SQLScripts = SQLScripts
.OrderBy(T => int.Parse(T.Split('.')[0]))
.ToArray();
答案 1 :(得分:3)
你需要所谓的“自然排序”。
实际上有一个名为StrCmpLogicalW()
的本机Windows API比较器可用于执行此操作,通过P / Invoke调用它。
您可以使用它来编写通用字符串比较器,然后将其传递给Array.Sort()
。这在许多情况下很有用,因此它可以添加到类库中。
这是一个完整的可编辑示例:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
namespace ConsoleApp1
{
[SuppressUnmanagedCodeSecurity]
internal static class NativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
public sealed class NaturalStringComparer: IComparer<string>
{
public int Compare(string a, string b)
{
return NativeMethods.StrCmpLogicalW(a, b);
}
}
sealed class Program
{
void run()
{
string[] array =
{
"1.Script_DBScript_03122014",
"10.Script_DBScript_03122014",
"11.Script_DBScript_03122014",
"12.Script_DBScript_03122014",
"2.Script_DBScript_03122014",
"20.Script_DBScript_03122014",
"21.Script_DBScript_03122014",
"22.Script_DBScript_03122014"
};
Array.Sort(array); // Sorts in the wrong order.
foreach (var filename in array)
Console.WriteLine(filename);
Console.WriteLine("\n");
Array.Sort(array, new NaturalStringComparer()); // Sorts correctly.
foreach (var filename in array)
Console.WriteLine(filename);
}
static void Main(string[] args)
{
new Program().run();
}
}
}
但是,如果您只是更改字符串的格式以将前导零添加到所有数字部分,则这一切都变得不必要了。
答案 2 :(得分:2)
您必须将字符串拆分为.
并将数字部分解析为int
,然后您可以按数字排序。
您可以使用LINQ:
SQLScripts = SQLScripts
.Select(str => {
string[] split = str.Split('.');
string numberPart = split[0].Trim();
int i;
bool isNumber = int.TryParse(numberPart, out i);
int? number = isNumber ? i : (int?)null;
return new { str, split, numberPart, number };
})
.OrderByDescending(x => x.number.HasValue)
.ThenBy(x => x.number)
.Select(x => x.str)
.ToArray();
说明:
此查询首先选择包含所有相关信息的匿名类型,然后按Nullable<int>.HasValue
属性排序,该属性是一个布尔值,指示是否可以将第一个标记解析为int
。由于我true
比使用false
OrderByDescending
更高,因为我希望不可解析的字符串位于底部。
之后(ThenBy
)它将按数字本身排序以获得数字顺序而不是字典顺序。最后一步是从匿名类型中选择字符串,并使用ToArray
获取新的有序string[]
。