C#排序字母数字列表

本文关键字:数字 列表 排序 | 更新日期: 2023-09-27 18:29:09

假设我有一个多部分问题列表,每个问题都有一个QuestionNumber,如11a1b22a等等。问题是,它将使用像一样的字典排序,而不是使用正确的顺序

1
11
11a
11b
1a
1b
2
22

到目前为止,我有一个自定义比较器:

public class QuestionCompare : IComparer<Question>
{
    public int Compare(Question x, Question y)
    {
        string a = x.QuestionNumber;
        string b = y.QuestionNumber;
        if (a == b)
        {
            return 0;
        }
        int aInt;
        bool aBool = Int32.TryParse(new String(a.Where(Char.IsDigit).ToArray()), out aInt);
        int bInt;
        bool bBool = Int32.TryParse(new String(b.Where(Char.IsDigit).ToArray()), out bInt);
        if (aBool)
        {
            if (bBool)
            {
                if (aInt > bInt)
                {
                    return 1;
                }
                else if (aInt < bInt)
                {
                    return -1;
                }
                else
                {
                    string aLetter = new String(a.Where(Char.IsLetter).ToArray());
                    string bLetter = new String(a.Where(Char.IsLetter).ToArray());
                    return StringComparer.CurrentCulture.Compare(aLetter, bLetter);
                }
            }
            else
            {
                return 1;
            }
        }
        else
        {
            if (bBool)
            {
                return -1;
            }
            else
            {
                return StringComparer.CurrentCulture.Compare(a, b);
            }
        }
        return 0;
    }
}

你可以打电话给Array.Sort(questionArray,new QuestionCompare()),把问题按正确的顺序排列。

然而,我觉得这是一个常见且定义良好的顺序,所以我想知道是否有更好的实现,甚至可能是.Net框架中内置的东西。

C#排序字母数字列表

这个比较器工作正常,而且短了一点。

public class QuestionCompare : IComparer<Question>
{
    public int Compare(Question x, Question y)
    {
        string a = x.QuestionNumber;
        string b = y.QuestionNumber;
        var aDigits = new string(a.TakeWhile(c => char.IsDigit(c)).ToArray());
        var bDigits = new string(b.TakeWhile(c => char.IsDigit(c)).ToArray());
        int aInt = String.IsNullOrEmpty(aDigits) ? 0 : int.Parse(aDigits);
        int bInt = String.IsNullOrEmpty(bDigits) ? 0 : int.Parse(bDigits);
        return aInt != bInt ? aInt.CompareTo(bInt) : a.CompareTo(b);
    }
}