简体   繁体   中英

Alpha numeric sorting in C#

I have CSV data like this:

Number;Version
1;AA.1
1;A01.1
1;A01.2
1;Z.7

Here, I need to sort the Version column descending like following:

Number;Version
1;AA.1
1;Z.7
1;A01.2
1;A01.1

So if you see, the Z.7 entry should come after AA.1. basically the descending sorting should be done like:

Sorted Version:

BB
AA
Z
C
B
A

I've already tried the Alphanum Algorithm discussed at http://www.DaveKoelle.com as well Natural Sort Comparer at http://www.codeproject.com/Articles/22517/Natural-Sort-Comparer . It does everything what I want except the sorting mentioned above.

So, this looks like you need to sort on some custom logic as followed in the CSV file. To perform this you must implement IComparer<string> on a class and implement the Compare method based on your requirement. Looks like in your case, you need to first split the string into two parts, the alphabets part and numeric part (using regular expression), then compare the string first, if both are same then compare number part and return the value accordingly.

You can then use this Comparer class to sort them.

Update

Code sample

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

To use this Comparer

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

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

Caution: I have proved the above code is only correct and not otherwise. There can be some edge cases where it may not be working as expected

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM