Sorting of list contained strings having alphabetic/numeric

前端 未结 2 748
长情又很酷
长情又很酷 2020-12-12 04:46

I want to make sort list of strings which contains strings of alphabetically, mixture of alphabetic and numeric and numeric only.I have requirement from my client to sort li

相关标签:
2条回答
  • 2020-12-12 05:23
    unsortedStringList.Sort(new AlphanumComparatorFastString());
    

    AlphanumComparator:

        public class AlphanumComparatorFastString : IComparer<String>
        {
            public int Compare(string s1, string s2)
            {
                if (s1 == null)
                    return 0;
    
                if (s2 == null)
                    return 0;
    
                int len1 = s1.Length;
                int len2 = s2.Length;
                int marker1 = 0;
                int marker2 = 0;
    
                // Walk through two the strings with two markers.
                while (marker1 < len1 && marker2 < len2)
                {
                    char ch1 = s1[marker1];
                    char ch2 = s2[marker2];
    
                    // Some buffers we can build up characters in for each chunk.
                    char[] space1 = new char[len1];
                    int loc1 = 0;
                    char[] space2 = new char[len2];
                    int loc2 = 0;
    
                    // Walk through all following characters that are digits or
                    // characters in BOTH strings starting at the appropriate marker.
                    // Collect char arrays.
                    do
                    {
                        space1[loc1++] = ch1;
                        marker1++;
    
                        if (marker1 < len1)
                        {
                            ch1 = s1[marker1];
                        }
                        else
                        {
                            break;
                        }
                    } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
    
                    do
                    {
                        space2[loc2++] = ch2;
                        marker2++;
    
                        if (marker2 < len2)
                        {
                            ch2 = s2[marker2];
                        }
                        else
                        {
                            break;
                        }
                    } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
    
                    // If we have collected numbers, compare them numerically.
                    // Otherwise, if we have strings, compare them alphabetically.
                    string str1 = new string(space1);
                    string str2 = new string(space2);
    
                    int result;
    
                    if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
                    {
                        int thisNumericChunk = int.Parse(str1);
                        int thatNumericChunk = int.Parse(str2);
                        result = thisNumericChunk.CompareTo(thatNumericChunk);
                    }
                    else
                    {
                        result = str1.CompareTo(str2);
                    }
    
                    if (result != 0)
                    {
                        return result;
                    }
                }
                return len1 - len2;
            }
        }
    

    as found on http://www.dotnetperls.com/alphanumeric-sorting

    0 讨论(0)
  • 2020-12-12 05:34

    Try this:

    var text = "111,111A,222,411G,300,411Z,G411,AG500,A111,AZ600,ABQ,ZZZ,AAN";
    var list = text.Split(',').ToList();
    var result = list.OrderBy(i => i, new StringCompare());
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
    

    StringCompare class:

    class StringCompare : IComparer<string>
    {
        string[] exps = new[] { @"^\d+$", @"^\d+[a-zA-Z]+$", @"^[a-zA-Z]\d+$", @"^[a-zA-Z]+\d+$" };
        public int Compare(string x, string y)
        {
            for (int i = 0; i < exps.Length; i++)
            {
                var isNumberx = Regex.IsMatch(x, exps[i]);
                var isNumbery = Regex.IsMatch(y, exps[i]);
    
                if (isNumberx && isNumbery)
                    return string.Compare(x, y);
                else if (isNumberx)
                    return -1;
                else if (isNumbery)
                    return 1;
                //return string.Compare(x, y);
            }
            return string.Compare(x, y);
        }
    }
    

    You will get:

    111
    222
    300
    111A
    411G
    411Z
    A111
    G411
    AG500
    AZ600
    AAN
    ABQ
    ZZZ
    
    0 讨论(0)
提交回复
热议问题