【问题标题】:Alpha numeric sorting in C#C#中的字母数字排序
【发布时间】:2012-10-11 21:10:11
【问题描述】:

我有这样的 CSV 数据:

编号;版本
1;AA.1
1;A01.1
1;A01.2
1;Z.7

在这里,我需要对 Version 列进行降序排序,如下所示:

编号;版本
1;AA.1
1;Z.7
1;A01.2
1;A01.1

因此,如果您看到,Z.7 条目应该在 AA.1 之后。基本上降序排序应该是这样的:

排序后的版本:

BB
AA
Z
C

一个

我已经试过了 Alphanum 算法也在http://www.DaveKoelle.com 上讨论过 自然排序比较器 http://www.codeproject.com/Articles/22517/Natural-Sort-Comparer。除了上面提到的排序之外,它可以满足我的所有需求。

【问题讨论】:

  • 您没有描述您的排序标准。为什么Z.7 应该在AA.1 之后?
  • 是的。在 CSV 文件中,版本 AA.1 被认为高于版本 Z.7。所以我想这样排序。

标签: c# algorithm sorting alphanumeric


【解决方案1】:

因此,您似乎需要按照 CSV 文件中的一些自定义逻辑进行排序。要执行此操作,您必须在类上实现 IComparer<string> 并根据您的要求实现 Compare 方法。看起来在你的情况下,你需要先将字符串分成两部分,字母部分和数字部分(使用正则表达式),然后首先比较字符串,如果两者相同,则比较数字部分并相应地返回值。

然后您可以使用这个Comparer 类对它们进行排序。

更新

代码示例

public class CustomStringComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        int? result;
        if (AnyParamIsNull(x, y, out result))
        {
            return result.Value;
        }

        string x1, y1;
        double x2, y2;
        SplitInput(x, out x1, out x2);
        SplitInput(y, out y1, out y2);
        if (x1.Length == y1.Length)
        {
            result = string.Compare(x1, y1);
            if (result.Value == 0)
            {

                if (x2 < y2)
                {
                    return -1;
                }
                else if (x2 > y2)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }


            }
            else
            {
                return result.Value;
            }
        }
        else
        {
            //To make AA before Z when desending
            return x1.Length - y1.Length;
        }

    }

    private bool SplitInput(string input, out string alphabets, out double number)
    {
        Regex regex = new Regex(@"\d*[.]?\d+");
        Match match = regex.Match(input);
        if (match.Success)
        {
            number = double.Parse(match.Value, CultureInfo.InvariantCulture);
            alphabets = input.Replace(match.Value, "");
            return true;
        }
        else
        {
            throw new ArgumentException("Input string is not of correct format", input);
        }
    }


    private bool AnyParamIsNull(string x, string y, out int? result)
    {
        result = null;
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're 
                // equal.  
                result = 0;
                return true;
            }
            else
            {
                // If x is null and y is not null, y 
                // is greater.  
                result = -1;
                return true;
            }
        }
        else
        {
            // If x is not null... 
            // 
            if (y == null)
            // ...and y is null, x is greater.
            {
                result = 1;
                return true;
            }
        }
        return false;
    }
}

使用这个比较器

        List<string> input = new List<string>()
        {
            "AA.1",
            "A01.1",
            "A01.2",
            "Z.7"
        };

        input.Sort(new CustomStringComparer());
        //To sort decending
        input.Reverse();

注意:我已经证明上面的代码是正确的,否则是不正确的。在某些极端情况下,它可能无法按预期工作

【讨论】:

  • 你是对的拉梅什。对于某些边缘情况,它不能按我的意愿工作,但我修改了该部分,现在它可以根据我的需要完全工作。
猜你喜欢
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 2015-06-22
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多