简体   繁体   中英

Sorting of list contained strings having alphabetic/numeric

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 like this:

Sort in tablelist type object contains Item Code: 111,111A,222,411G,300,411Z,G411,AG500,A111,AZ600,ABQ,ZZZ,AAN etc

Required result: First show numbers (like 111 then 222 then 300 etc...) Next will be numbers with Letters (like 111A then 411G then 411Z etc...) Next Letters with numbers (like A111 then G411 then AG500 then AZ600 etc. ...) next letters only (like AAN then ABQ then ZZZ etc....)

So the string can be anything.But I want to get sort as required result. So please help me regarding it.

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

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

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