当名称包含字母和数字时进行排序
本文关键字:排序 数字 包含字 | 更新日期: 2023-09-27 18:15:27
我有以下数组
[0] = GB_22_T0001.jpg
[1] = GB_22_T0002.jpg
[2] = GB_22_T0003.jpg
[3] = GB_22_T0006.jpg
[4] = GB_22_T0007.jpg
[5] = GB_22_T0008.jpg
[6] = GB_22_T0009.jpg
[7] = GB_22_T00010.jpg
[8] = GB_22_T00011.jpg
[9] = GB_22_T00012.jpg
[10] = GB_22_T00013.jpg
我把这些项目放在一个列表框中,并注意到'GB_22_T00010'直接出现在'GB_22_T0001'之后,而不是'GB_22_T0002'
似乎是c#的一个共同问题,但找不到一个共同的答案。
我尝试用array .sort(data)排序数组,也尝试了LinQ的OrderBy方法,但都没有帮助。
谁有解决办法?
这是我的代码排序字符串有字母和数字字符。
首先,这个扩展方法:public static IEnumerable<string> AlphanumericSort(this IEnumerable<string> me)
{
return me.OrderBy(x => Regex.Replace(x, @"'d+", m => m.Value.PadLeft(50, '0')));
}
然后,在代码的任何地方使用它,像这样:
List<string> test = new List<string>() { "The 1st", "The 12th", "The 2nd" };
test = test.AlphanumericSort();
它是如何工作的?
Original | Regex Replace | The | Returned
List | Apply PadLeft | Sorting | List
| | |
"The 1st" | "The 001st" | "The 001st" | "The 1st"
"The 12th" | "The 012th" | "The 002nd" | "The 2nd"
"The 2nd" | "The 002nd" | "The 012th" | "The 12th"
适用于多个数字:
Alphabetical Sorting | Alphanumeric Sorting
|
"Page 21, Line 42" | "Page 3, Line 7"
"Page 21, Line 5" | "Page 3, Line 32"
"Page 3, Line 32" | "Page 21, Line 5"
"Page 3, Line 7" | "Page 21, Line 42"
希望这对你有帮助。
GB_22_T0001
是字符串而不是数字。所以它是按字典顺序排序的,而不是按数字排序的。因此,您需要将字符串的一部分解析为int
。
var ordered = array.Select(Str => new { Str, Parts=Str.Split('_') })
.OrderBy(x => int.Parse(x.Parts.Last().Substring(1)))
.Select(x => x.Str);
Split('_')
在分隔符_
上将字符串分成子字符串。最后一个子字符串包含您的数值。然后我使用String.Substring
只取int.Parse
的数字部分(删除开始的T
)。该整数用于Enumerable.OrderBy
。最后一步是只选择字符串而不是匿名类型。
Edit:这是支持Paths
的版本:
var ordered = array.Select(str => {
string fileName = Path.GetFileNameWithoutExtension(str);
string[] parts = fileName.Split('_');
int number = int.Parse(parts.Last().Substring(1));
return new{ str, fileName, parts, number };
})
.OrderBy(x => x.number)
.Select(x => x.str);
Windows有一个内置的比较函数,你可以使用它来比较这样的字符串(字符串和数字的混合):StrCmpLogicalW
你可以使用它作为ic比较器的核心来完成你的排序。
这个博客条目有很多关于这个的细节:http://gregbeech.com/blog/natural-sort-order-of-strings-and-files
效果很好。
编辑:我使用的实现基于上面的博客:
public sealed class NaturalStringComparer : IComparer<string>
{
public static readonly NaturalStringComparer Default = new NaturalStringComparer();
public int Compare(string x, string y)
{
return SafeNativeMethods.StrCmpLogicalW(x, y);
}
}
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
然后使用LINQ:
var sortedItems = items.OrderBy(i => i, new NaturalStringComparer());