C# 排序格式不正确
我有一个字符串数组,其中包含如下文件名C# 排序格式不正确,c#,arrays,C#,Arrays,我有一个字符串数组,其中包含如下文件名 1.Script_DBScript_03122014 我想对该数组进行排序,因此我编写了以下代码: Array.Sort(SQLScripts); 但排序数组的生成方式如下: 1.Script_DBScript(otherdetails)_03122014 10.Script_DBScript(otherdetails)_03122014 11.Script_DBScript(otherdetails)_03122014 12.Script_
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");
得到的结果是非常常见的字符串排序。您需要的是数字或数字排序 在这种情况下,您可能需要解析字符串,从第一个点的左侧提取数字,使用包含数字的int.Parsestring等方法,然后按整数排序 我会这样做,但是我不建议在不了解您的操作的情况下复制粘贴我的代码:
SQLScripts = SQLScripts
.OrderBy(T => int.Parse(T.Split('.')[0]))
.ToArray();
得到的结果是非常常见的字符串排序。您需要的是数字或数字排序 在这种情况下,您可能需要解析字符串,从第一个点的左侧提取数字,使用包含数字的int.Parsestring等方法,然后按整数排序 我会这样做,但是我不建议在不了解您的操作的情况下复制粘贴我的代码:
SQLScripts = SQLScripts
.OrderBy(T => int.Parse(T.Split('.')[0]))
.ToArray();
你必须把弦分开。并将数字部分解析为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.HasValue属性排序,该属性是一个布尔值,指示第一个标记是否可以解析为int。由于true高于false,所以我使用OrderByDescending,因为我希望不可解析的字符串位于底部
之后,它将按数字本身排序,以获得数字顺序,而不是字典顺序。最后一步是从匿名类型中选择字符串,并使用ToArray获取新的有序字符串[]。您必须按顺序拆分字符串。并将数字部分解析为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.HasValue属性排序,该属性是一个布尔值,指示第一个标记是否可以解析为int。由于true高于false,所以我使用OrderByDescending,因为我希望不可解析的字符串位于底部
之后,它将按数字本身排序,以获得数字顺序,而不是字典顺序。最后一步是从匿名类型中选择字符串,并使用ToArray获取新的有序字符串[]。您需要所谓的自然排序顺序 实际上,有一个名为strmplogicalw的本机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();
}
}
}
但是,如果您只是更改字符串的格式,将前导零添加到所有数字部分,这一切就变得不必要了。您需要所谓的自然排序顺序 实际上,有一个名为strmplogicalw的本机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();
}
}
}
但是,,如果您只是更改字符串的格式,将前导零添加到所有数字部分,则这一切都变得不必要。获取错误-输入字符串的格式不正确。@RazoR我可以查看输入字符串吗?获取错误-输入字符串的格式不正确。@RazoR我可以查看输入字符串吗?字符串按字母顺序排序默认情况下。有时可以通过调整文件名来解决此问题,例如0001.Script_DBScript_03122014。这也是为什么有些文件名使用诸如YYYYMMDD的日期格式,即2014年3月13日的20140313,甚至同一日期下午2:57:01的20140313_145701。对于某些实现,可能重复的字符串默认按字母顺序排序。有时可以通过调整文件名来解决此问题,例如0001.Script_DBScript_03122014。这也是为什么有些文件名使用诸如YYYYMMDD的日期格式,即2014年3月13日的20140313,或者甚至同一日期下午2:57:01的20140313_145701。对于某些实现,可能的重复请查看执行的代码,没有错误,但数组排序不正确,仍然得到相同的排序输出。@RazoR:已使用示例字符串对其进行了测试并正确排序:1.Script_DBScript_03122014,2.Script_DBScript_03122014,10.Script_DBScript_03122014,11.Script_DBScript_03122014,12.Script_DBScript_03122014,20.Script_DBScript_DBScript_03122014,21.Script_DBScript_
22014,22.Script_DBScript_03122014,…实际上,DBScript名称在每个index@RazoR字体没什么区别。开头的数字真的存在吗,还是您添加它们以提供索引?执行的代码没有错误,但数组没有正确排序,仍然得到相同的排序输出。@RazoR:它已使用示例字符串进行测试并正确排序:1.Script_DBScript_03122014,2.Script_DBScript_03122014,10.Script_DBScript_03122014,11.Script_DBScript_03122014,12.Script_DBScript_03122014,20.Script_DBScript_03122014,21.Script_DBScript_03122014,22.Script_DBScript_03122014,……实际上,DBScript的名称在每一天都会发生变化index@RazoR字体没什么区别。开始时的数字真的存在吗?还是你加上它们来给出一个索引?