Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong string ordering in C#

I ran this:

void Main()
{
    List<string> strings = new List<string>{"aaa", "z", "a"};
    Console.WriteLine(string.Join("\n", strings.OrderBy(k => k)));
}

And the output is:

a
z
aaa

This can't be right! I was expecting

a
aaa
z

What could be the problem?

like image 787
elnigno Avatar asked Sep 05 '25 11:09

elnigno


2 Answers

I've realized that OrderBy uses the current locale to sort strings. In my case the locale is Danish, in which "aa" comes after "z", as it represents the letter "å", which is appended at the end of the alphabet.

This came as a surprise to me because I was expecting English sorting and I hadn't realized that the locale had been Danish all along; many other settings on my system are set to English, including the language. This tricked my expectation into being wrong.

To get the ordering I expect, it was sufficient to pass StringComparer.InvariantCulture to OrderBy:

void Main()
{
    List<string> strings = new List<string>{"aaa", "z", "a"};
    Console.WriteLine(string.Join("\n", strings.OrderBy(k => k, StringComparer.InvariantCulture)));
}

Output:

a
aaa
z
like image 89
elnigno Avatar answered Sep 09 '25 02:09

elnigno


That's happen because your default comparer sorts by length first. You didn't try to sort a collection with mixed cases, like:

List<string> strings = new List<string>{"aaa", "D", "z", "a"};

In the answer posted by elnigno it will produce an output like:

a
aaa
D
z

If you need to have them ordered by their codes in coding table, then most likely you'll prefer this way:

var keywords = new List<string> { "aaa", "D", "z", "a" };
Console.WriteLine(string.Join("\n", keywords.OrderBy(k => k, StringComparer.Ordinal)));

And output will be like:

D
a
aaa
z
like image 30
Serhiy Chupryk Avatar answered Sep 09 '25 01:09

Serhiy Chupryk