【问题标题】:Sort number string mapped strings排序数字字符串映射的字符串
【发布时间】:2014-07-14 22:15:48
【问题描述】:

我们有一个关于排序字符串的问题。在这种情况下排序不起作用

1-A 1-B 10-A 10-B 9-A 9-B ...

我们真正想要的是

1-A 1-B 9-A 9-B 10-A 10-B 如果我们将其排序为字符串,结果将类似于第一部分。如果我们解析然后排序,那么我们如何对其余的 A 和 B 进行排序? c#有什么简单的解决方案吗?

谢谢;

【问题讨论】:

  • C# Natural sort order 问题中涵盖了非常相似的问题(将文件名排序为“foo123.txt”)。您可以在您最喜欢的搜索引擎上使用“C# 自然排序”作为搜索词找到更多信息。

标签: c# sorting natural-sort


【解决方案1】:

您可以implement own comparer 放置自定义比较逻辑。然后你可以use this comparer instance进行排序。

【讨论】:

    【解决方案2】:

    我建议使用IComparer

    它很容易实现并按照您所追求的方式进行排序,示例。

    1.txt
    10.txt
    3.txt
    a10b1.txt
    a1b1.txt
    a2b1.txt
    a2b11.txt
    a2b2.txt
    b1.txt
    b10.txt
    b2.txt  
    

    排序到

    1.txt
    3.txt
    10.txt
    a1b1.txt
    a2b1.txt
    a2b2.txt
    a2b11.txt
    a10b1.txt
    b1.txt
    b2.txt
    b10.txt
    

    【讨论】:

      【解决方案3】:

      只需使用以下代码

      string[] strArr = new string[] {"1-A", "1-B", "9-A", "9-B", "10-A", "10-B"};
      var q = from t in strArr select new { FirstPart =Convert.ToInt32(t.Split('-')[0]), SecondPart = t.Split('-')[1] };
      
      string[] resArr = q.OrderBy(p => p.FirstPart).ThenBy(p => p.SecondPart).Select(p=> string.Concat(p.FirstPart, "-", p.SecondPart)) .ToArray();
      

      【讨论】:

        【解决方案4】:

        一种方式,可以使用LINQ的OrderBy+ThenBy

        string[] strings = {"1-A", "1-B", "10-A", "10-B", "9-A", "9-B"}; 
        int i = 0;
        var orderedStrings = strings
           .Select(str => new { arr = str.Split('-'), str })
           .Where(x => x.arr.Length == 2 && int.TryParse(x.arr[0], out i))
           .Select(x => new { x.str, x.arr, num = int.Parse(x.arr[0])})
           .OrderBy(x => x.num)
           .ThenBy(x => x.arr[1])
           .Select(x => x.str); 
        

        假定字符串始终由- 分隔,包含两部分,第一部分始终是intWhere 确保了这一点,格式无效的字符串将被忽略。

        如果您想将有序查询重新分配给您的string[],您需要创建一个新查询:

        strings = orderedStrings.ToArray();
        

        【讨论】:

          【解决方案5】:

          您正在寻找“自然排序顺序”。

          事实证明,我们可以使用 P/Invoke 调用 the Windows API provides a StrCmpLogicalW() function 来解决问题。

          假设您正在尝试对List<> 或数组进行排序,您可以将其包装在扩展方法中以使其更易于调用:

          public static class ListAndArrayExt
          {
              [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
              private static extern int StrCmpLogicalW(string lhs, string rhs);
          
              public static void SortNatural(this List<string> self)
              {
                  self.Sort(StrCmpLogicalW);
              }
          
              public static void SortNatural(this string[] self)
              {
                  Array.Sort(self, StrCmpLogicalW);
              }
          }
          

          然后您可以使用它以自然排序顺序对List&lt;&gt; 进行排序。这是一个完整的可编译控制台应用程序来演示:

          using System;
          using System.Collections.Generic;
          using System.Runtime.InteropServices;
          
          namespace ConsoleApp1
          {
              public static class ListAndArrayExt
              {
                  [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
                  private static extern int StrCmpLogicalW(string lhs, string rhs);
          
                  public static void SortNatural(this List<string> self)
                  {
                      self.Sort(StrCmpLogicalW);
                  }
          
                  public static void SortNatural(this string[] self)
                  {
                      Array.Sort(self, StrCmpLogicalW);
                  }
              }
          
              class Program
              {
                  void run()
                  {
                      var strings = new List<string>
                      {
                          "1-A",
                          "1-B",
                          "10-A",
                          "10-B",
                          "9-A",
                          "9-B"
                      };
          
                      strings.SortNatural();
          
                      foreach (var s in strings)
                          Console.WriteLine(s);
                  }
          
                  static void Main()
                  {
                      new Program().run();
                  }
              }
          }
          

          这样打印出字符串:

          1-A
          1-B
          9-A
          9-B
          10-A
          10-B
          

          【讨论】:

            【解决方案6】:

            您需要实现自定义的比较器,它会根据您的喜好来编译字符串。例如NaturalComparer

            【讨论】:

              【解决方案7】:

              尝试使用

              数组列表

              然后使用

              ArrayList.Sort();

              它将对您的数组进行排序。

              【讨论】:

              • -1:问题明确指出“排序在这种情况下不起作用”......而且使用ArrayList 几乎总是坏主意。
              猜你喜欢
              • 1970-01-01
              • 2012-08-21
              • 1970-01-01
              • 1970-01-01
              • 2021-11-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多