如何在C#中创建自定义通用数字文本比较器以对数字/字符串列表进行排序? [英] How to create custom common number-text comparer in C# to sort numeric/string list?

查看:110
本文介绍了如何在C#中创建自定义通用数字文本比较器以对数字/字符串列表进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有数字文本列表,我想创建通用的自定义比较器逻辑以使用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升序-> 不适用,-,--888,-0.98,0.00,100 对于StringList升序-> 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);

解决方案

您的代码正常工作. Se 此处.结果:

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

问题是您的假设,即"和-"在字母后面.由于它们在 ascii表中的位置较低,因此他们排在第一位./p>

这将是一个简单的修复.在此处

尝试

    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;
    }

I have number-text list and I want to create common custom comparer logic to sort this list(s) using C#. E.g.

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

which contains some special characters like --, N/A,Space etc. And expected result after sort will be - For NemericList Ascending -> N/A, -- , -888 , -0.98 , 0.00 , 100 For StringList Ascending -> Jim, Ken, N/A, Peter, Smith, Empty, --

I created following custom comparer logic which does some level of sorting but not matching with the expected result. Please suggest me the way to achieve this.

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);

解决方案

Your code works correct. Se here. Results:

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

The problem is your assumption, that the "" and "--" come after letters. Since they have a lower position in the ascii-table they come first.

This would be a simple fix. Try here

    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;
    }

这篇关于如何在C#中创建自定义通用数字文本比较器以对数字/字符串列表进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆