列表<;字符串>;C#自定义排序.数字后下划线

本文关键字:排序 数字 自定义 下划线 gt lt 字符串 列表 | 更新日期: 2023-09-27 18:02:03

我有一个列表:"a_a"、"a1a"、"aaa"。

我需要按以下方式排序:"a1a","a_a","aaa"。

换句话说,我需要"_"符号出现在数字之后,但出现在字母之前。

我知道使用自定义比较器是可能的,但我还没有找到任何好的解决方案来解决这个问题,只有肮脏的黑客,例如:

Compare(string x, string y){
return Comparer.Default.Compare(x.Replace("_", "9z"), y.Replace("_", "9z"));
}

列表<;字符串>;C#自定义排序.数字后下划线

根据标准ASCII表:

  '0'..'9' have codes 0x30..0x39
  '_'      -/-        0x5F
  'a'..'z' -/-        0x61..0x7A

因此,由于代码的顺序正确,您可以使用顺序比较:

  List<String> list = new List<string> {
    "a1a", "a_a", "aaa"
  };
  list.Sort((Comparison<String>) (
    (String left, String right) => {
       return String.CompareOrdinal(left, right);
    }
  ));
  ...
  // a1a, a_a, aaa
  Console.Write(String.Join(", ", list)); 

这里有一个自定义的字符串比较器,它将使用一个字符比较器,因此您可以根据需要比较字符。话虽如此,在实现您自己的比较器之前,请确保StringComparer.Ordinal不会完成此工作。

public class CustomStringComparer : IComparer<string>
{
    readonly IComparer<char> charComparer;
    public CustomStringComparer(IComparer<char> charComparer)
    {
        this.charComparer = charComparer;
    }
    public int Compare(string a, string b)
    {
        int result = 0;
        for (int i = 0; (i < a.Length || i < b.Length) && result == 0 ; i++)
        {
            if (i >= a.Length || i >= b.Length)
            {
                return i >= a.Length ? -1 : 1;
            }
            result = charComparer.Compare(a[i], b[i]);
        }
        return result;
    }
}