1

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

vivek
  • 21
  • 4
  • Sort method returns the desired result... not the _Expected_ one that seems to be wrong; could you please add real code, or at least real data? – Salvatore Giuffrida Nov 20 '22 at 15:51
  • Any specific requirements on how to order within the special characters? The standard order function gives: "@123Test", "@Red", "&While", "#Test", "%54Sun", "123@Test", "Dom", "Hello", "Left". – Klaus Gütter Nov 20 '22 at 16:04
  • @KlausGütter No specific requirement within special characters. the order should be first special characters, then numbers and then alphabets. Thanks. – vivek Nov 20 '22 at 16:08
  • 1
    Then `input.OrderBy(x => x)` is perfectly fine. – Klaus Gütter Nov 20 '22 at 16:09
  • @KlausGütter I tried input.OrderBy(x => x) the result I have attached above when I click on column for sort in descending – vivek Nov 20 '22 at 16:11
  • Better add this as text, not as image. Your result seems to use different input that the example in your question, right? – Klaus Gütter Nov 20 '22 at 16:16
  • Yes its different example – vivek Nov 20 '22 at 16:33

2 Answers2

1

As the standard string comparison does exactly that, you can just use OrderBy:

var input = new[] { "Hello", "#Test", "@Red", "&While", "123@Test", "@123Test", "%54Sun", "Dom", "Left" };
foreach (var s in input.OrderBy(x => x)) Console.WriteLine(s);

Gives:

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

Since the string comparison is culture-dependent, this might be different depending on your current culture. If you want it culture-independent, use e.g. OrderBy(x => x, StringComparer.InvariantCulture).

Klaus Gütter
  • 11,151
  • 6
  • 31
  • 36
0

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
Renat
  • 7,718
  • 2
  • 20
  • 34