Search code examples
c#linqsortingspecial-characters

How to sort a Alphanumeric string with special characters in C# using Linq?


How to sort a Alphanumeric string with special characters in C# using Linq? Order should be first special characters, then numbers and then alphabets.

Example :

Input - { Hello, #Test, @Red, &While, 123@Test, @123Test, %54Sun, Dom, Left }

Expected - { @123Test, %54Sun, @Red, #Test, &While, 123@Test, Dom, Hello, Left }

enter image description here


Solution

  • You may use custom implementation of IComparer, then pass it to OrderBy call. E.g.:

    public class SpecialCharactersNumbersLettersComparer : IComparer<string>
    {
        private readonly IComparer<string> defaultComparer = StringComparer.InvariantCulture;
        
        private static int OrderOfChar(char ch)
        {
            if(Char.IsLetter(ch))
                return 2;
            if(Char.IsDigit(ch))
                return 1;
            return 0;
        }
        
        public int Compare(string left, string right)
        {
            if(string.IsNullOrEmpty(left)
              || string.IsNullOrEmpty(right)) {
                return defaultComparer.Compare(left, right);
            }
            
            var leftChar = left[0];
            var rightChar = right[0];
            var leftOrder = OrderOfChar(leftChar);
            var rightOrder = OrderOfChar(rightChar);
            
            if(leftOrder == rightOrder)
                return defaultComparer.Compare(left, right);
            
            if(leftOrder > rightOrder)
                return 1;
            return -1;
        }
    }
    
    public static List<string> SortSpecialCharactersNumbersAlphabet(IEnumerable<string> input)
    {
        return input.OrderBy(_ => _, new SpecialCharactersNumbersLettersComparer())
            .ToList();
    }
    

    Used as:

    Console.WriteLine(string.Join(", ",
        SortSpecialCharactersNumbersAlphabet(new [] {
        "Hello", "#Test", "@Red", "&While", "123@Test", "@123Test", "%54Sun", "Dom", "Left"})));
    

    produces output:

    @123Test, @Red, &While, #Test, %54Sun, 123@Test, Dom, Hello, Left