5

我有以下数组

[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 方法,但它们都没有帮助。

有人有解决方案吗?

4

3 回答 3

5

这是我对同时具有字母和数字字符的字符串进行排序的代码。

首先,这个扩展方法:

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"

希望这会有所帮助。

于 2016-10-27T13:38:55.473 回答
2

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只取数字部分(去掉开头Tint.Parse。该整数用于Enumerable.OrderBy。最后一步是只选择字符串而不是匿名类型。

编辑:这是支持的版本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);
于 2013-05-24T16:09:45.100 回答
2

Windows 有一个内置的比较函数,您可以使用它来比较这样的字符串(字符串和数字的混合): StrCmpLogicalW

您可以使用它作为 IComparer 的胆量来进行排序。

这个博客条目有很多关于这个的细节: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());
于 2013-05-24T16:26:08.177 回答