如何在C#中创建自定义的公共数字文本比较器来对数字/字符串列表进行排序

本文关键字:数字 比较器 字符串 列表 排序 文本比较 文本 创建 自定义 | 更新日期: 2023-09-27 18:29:29

我有一个数字文本列表,我想创建通用的自定义比较器逻辑来使用C#对该列表进行排序。例如

var numericList = new List<string>{"100", "--", "-0.98", "N/A", "0.00", "-888"};
var stringList = new List<string> {"Smith", "--", "Peter", "", "Jim", "Ken", "NA"};

它包含一些特殊字符,如--、N/A、空格等。排序后的预期结果是-对于NemericList升序->N/A,--,-888,-0.98,0.00,100对于字符串列表升序->Jim、Ken、N/A、Peter、Smith、Empty、--

我创建了以下自定义比较器逻辑,它进行了一定程度的排序,但与预期结果不匹配。请给我建议实现这一目标的方法。

public class NumberTextComparer : IComparer<string>
    {
        public int Compare(string s1, string s2)
        {
            double number1, number2;
            var isS1Numeric = double.TryParse(s1, out number1);
            var isS2Numeric = double.TryParse(s2, out number2);
            if (isS1Numeric && isS2Numeric)
            {
                if (number1 > number2) return 1;
                if (number1 < number2) return -1;
                return 0;
            }
            return isS1Numeric ? 1 : (isS2Numeric ? -1 : String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase));
        }
    }
var comparer = new NumberTextComparer();
var numericSortedListASC = numericList.OrderBy(str => str, comparer);
var stringSortedListASC = stringList.OrderBy(str => str, comparer);

如何在C#中创建自定义的公共数字文本比较器来对数字/字符串列表进行排序

您的代码工作正常。Se在这里。结果:

--, N/A, -888, -0.98, 0.00, 100
, --, Jim, Ken, NA, Peter, Smith

问题是你的假设,"answers"--"在字母后面。由于他们在ascii表中的位置较低,所以他们排在第一位。

这将是一个简单的解决方案。试试这里

    public int Compare(string s1, string s2)
    {
        double number1, number2;
        var isS1Numeric = double.TryParse(s1, out number1);
        var isS2Numeric = double.TryParse(s2, out number2);
        if (isS1Numeric && isS2Numeric)
        {
            if (number1 > number2) return 1;
            if (number1 < number2) return -1;
            return 0;
        }
        if (isS1Numeric)
            return 1;
        if (isS2Numeric)
            return -1;
        bool s1StartsWithLetter = char.IsLetter(s1.FirstOrDefault());
        bool s2StartsWithLetter = char.IsLetter(s2.FirstOrDefault());
        if (s1StartsWithLetter == s2StartsWithLetter)
            return String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase);
        return s1StartsWithLetter ? -1 : 1;
    }