【问题标题】:How to sort descending a string list contains strings with alphabets & numbers in C# .net?如何在 C# .net 中对包含带有字母和数字的字符串的字符串列表进行降序排序?
【发布时间】:2021-01-27 12:21:00
【问题描述】:

我在字符串列表中有值,例如

AB1001_A
AB1001_B
AB1002_2
AB1002_C
AB1003_0
AB1003_
AB1003_B
AB1003_A
AB1001_0
AB1001_1
AB1001_2
AB1001_C
AB1002_B
AB1002_A

我想按升序和后缀按降序排序,如下所示

AB1001_2
AB1001_1
AB1001_0
AB1001_C
AB1001_B
AB1001_A
AB1002_0
AB1002_B
AB1002_A
AB1003_0
AB1003_B
AB1003_A
AB1003_

如何在 C#.net 中编写代码?

【问题讨论】:

  • 那么,你研究了什么,什么没用?
  • 我使用正则表达式尝试了 PadNumbers。但我不能仅以降序格式对后缀进行排序,而其余的以升序格式排序
  • 这能回答你的问题吗? How can I order a List<string>?
  • 预期结果中的后缀不是按降序排序的,因为如果它们是“C”、“B”、“A”、“2”、“1”、“0” "(数字按字母顺序排在字母之前)。
  • OrderByThenBy。但是你需要自己的比较器来按你想要的顺序对后缀进行排序

标签: c# .net list sorting alphanumeric


【解决方案1】:

这是一种很奇怪的排序,但如果你真的需要它,试试这样:

List<string> lItemsOfYourValues = new List<string>() {"AB1001_A","AB1001_B","AB1001_0" /*and next your values*/};

List<Tuple<string,string,string>> lItemsOfYourProcessedValues = new List<Tuple<string,string,string>>();
string[] arrSplitedValue;

for(int i = 0; i < lItemsOfYourValues.Count; i++) 
{

arrSplitedValue = lItemsOfYourValues[i].Split("_");

lItemsOfYourProcessedValues.add(new Tuple<string,string,string>(lItemsOfYourValues[i], arrSplitedValue[0], arrSplitedValue[1]));

}

List<string> lSortedValues = lItemsOfYourProcessedValues.OrderBy(o => o.Item2).ThenByDescending(o => o.Item3).Select(o => o.Item1).ToList();

【讨论】:

    【解决方案2】:

    您的预期结果中似乎有错误,因为AB1002_2 在输入中但不在预期结果中。

    假设这只是一个错误,并进一步假设后缀仅限于单个字符或数字,您可以通过编写一个特殊的比较器来解决排序问题,如下所示:

    static int compare(string x, string y)
    {
        var xParts = x.Split('_', StringSplitOptions.RemoveEmptyEntries);
        var yParts = y.Split('_', StringSplitOptions.RemoveEmptyEntries);
    
        if (xParts.Length != yParts.Length)
            return yParts.Length - xParts.Length; // No suffix goes after suffix.
    
        if (xParts.Length == 0) // Should never happen.
            return 0;
    
        int comp = string.Compare(xParts[0], yParts[0], StringComparison.Ordinal);
    
        if (comp != 0 || xParts.Length == 1)
            return comp;
    
        if (char.IsDigit(xParts[1][0]) && !char.IsDigit(yParts[1][0]))
            return -1; // Digits go before non-digit.
    
        if (!char.IsDigit(xParts[1][0]) && char.IsDigit(yParts[1][0]))
            return 1; // Digits go before non-digit.
    
        return string.Compare(yParts[1], xParts[1], StringComparison.Ordinal);
    }
    

    然后您可以使用它对字符串列表、数组或IEnumerable&lt;string&gt; 进行排序,如下所示:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace Demo
    {
        static class Program
        {
            static void Main()
            {
                var strings = new []
                {
                    "AB1001_A",
                    "AB1001_B",
                    "AB1002_2",
                    "AB1002_C",
                    "AB1003_0",
                    "AB1003_",
                    "AB1003_B",
                    "AB1003_A",
                    "AB1001_0",
                    "AB1001_1",
                    "AB1001_2",
                    "AB1001_C",
                    "AB1002_B",
                    "AB1002_A",
                };
    
                static int compare(string x, string y)
                {
                    var xParts = x.Split('_', StringSplitOptions.RemoveEmptyEntries);
                    var yParts = y.Split('_', StringSplitOptions.RemoveEmptyEntries);
    
                    if (xParts.Length != yParts.Length)
                        return yParts.Length - xParts.Length;
    
                    if (xParts.Length == 0)
                        return 0;
    
                    int comp = string.Compare(xParts[0], yParts[0], StringComparison.Ordinal);
    
                    if (comp != 0 || xParts.Length == 1)
                        return comp;
    
                    if (char.IsDigit(xParts[1][0]) && !char.IsDigit(yParts[1][0]))
                        return -1; // Digits go before non-digit.
    
                    if (!char.IsDigit(xParts[1][0]) && char.IsDigit(yParts[1][0]))
                        return 1; // Digits go before non-digit.
    
                    return string.Compare(yParts[1], xParts[1], StringComparison.Ordinal);
                }
    
                var stringList = strings.ToList();
                stringList.Sort(compare);
    
                Console.WriteLine("Sorted list:");
                Console.WriteLine(string.Join("\n", stringList));
    
                var stringArray = strings.ToArray();
                Array.Sort(stringArray, compare);
    
                Console.WriteLine("\nSorted array:");
                Console.WriteLine(string.Join("\n", stringArray));
    
                var sequence = strings.Select(element => element);
                var sortedSeq = sequence.OrderBy(element => element, Comparer<string>.Create(compare));
    
                Console.WriteLine("\nSorted sequence:");
                Console.WriteLine(string.Join("\n", sortedSeq));
            }
        }
    }
    

    Try it online on .Net Fiddle

    【讨论】:

      【解决方案3】:

      我终于得到了这个答案

      var mystrings = new []
                  {
                      "AB1001_A",
                      "AB1001_B",
                      "AB1002_2",
                      "AB1002_C",
                      "AB1003_0",
                      "AB1003_",
                      "AB1003_B",
                      "AB1003_A",
                      "AB1001_0",
                      "AB1001_1",
                      "AB1001_2",
                      "AB1001_C",
                      "AB1002_B",
                      "AB1002_A",
                  };
      
      
      mystrings.Cast<string>().OrderBy(x => PadNumbers(x));
      

      然后 PadNumbers 的功能如下所示

              public static string PadNumbers(string input)
              {
                  return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
              }
      

      【讨论】:

        猜你喜欢
        • 2021-02-22
        • 2017-08-11
        • 2022-11-23
        • 2021-08-12
        • 2016-10-28
        • 2013-06-05
        • 2019-03-28
        • 2012-08-07
        相关资源
        最近更新 更多