Search code examples
c#.netlinqsortingascii

LINQ OrderBy igorning case with true ASCII ordering


I'm trying to sort strings ("A", "_", "a") using LINQ in C# in ASCII order while ignoring case sensitivity. According to the ASCII table, the strings I'm interested are:

  • A = 65
  • _ = 95
  • a = 97

So I would expect the output to be

A, _, a

However I tried all the StringComparer variations, none of them give me the desired output. The following is my test program and output:

    string[] words = { "A", "_", "a" };
    
    var sortedWords = words.OrderBy(a => a, StringComparer.OrdinalIgnoreCase);
    Console.WriteLine("OrdinalIgnoreCase: " + string.Join(", ", sortedWords));

    sortedWords = words.OrderBy(a => a, StringComparer.CurrentCultureIgnoreCase);
    Console.WriteLine("CurrentCultureIgnoreCase: " + string.Join(", ", sortedWords));

    sortedWords = words.OrderBy(a => a, StringComparer.InvariantCultureIgnoreCase);
    Console.WriteLine("InvariantCultureIgnoreCase: " + string.Join(", ", sortedWords));

output:

OrdinalIgnoreCase: A, a, _

CurrentCultureIgnoreCase: _, A, a

InvariantCultureIgnoreCase: _, A, a

.net fiddle here.

How do I sort the array to get "A, _, a" according to the ASCII ordering?


Solution

  • Use StringComparer.Ordinal. By using StringComparer.OrdinalIgnoreCase you are ignoring the case, so probably it is silently converting everything to uppercase.

    From MSDN:

    OrdinalIgnoreCase:

    The StringComparer returned by the OrdinalIgnoreCase property treats the characters in the strings to compare as if they were converted to uppercase using the conventions of the invariant culture, and then performs a simple byte comparison that is independent of language.

    and

    Ordinal:

    The StringComparer returned by the Ordinal property performs a simple byte comparison that is independent of language.

    Sample correctly formatted: http://ideone.com/0YTUdr