3

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?

elnigno
  • 1,751
  • 14
  • 37
  • 3
    I guess that asking and answering your own (not-too-relevant, in my opinion: it is just a certain-culture peculiarities which should be taken into account when performing an alphabetical ordering) concern is OK. But writing "Any ideas?" in the question when you knew already the answer (which you wrote in the exact same minute) doesn't sound too right. – varocarbas Oct 29 '15 at 18:04
  • I've edited the question. – elnigno Oct 30 '15 at 09:57

2 Answers2

14

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
elnigno
  • 1,751
  • 14
  • 37
  • Hm, I've just noticed, are you answering your own question in such way? Like addressing "you" and "your"? :) – Serhiy Chupryk Oct 29 '15 at 17:56
  • Are you asking a question and answering it in the exact same minute? Certainly curious (also the +10). Anyway... the whole point of this comment is highlighting that this whole question is not a LINQ (or .NET or C#) problem/misunderstanding, but a misunderstanding of the given programmer about the culture used by the application. If in Danish the "a z aaa" is right why assuming that it should be "a aaa z"? If you want an English-based ordering, rely on the adequate culture (i.e., on virtually any culture as far as this is first time I have seen such an ordering). – varocarbas Oct 29 '15 at 17:57
  • @SerhiyChupryk He wrote the question and the answer in the exact same minute!! You answered a rhetorical question :) – varocarbas Oct 29 '15 at 17:58
  • 2
    @SerhiyChupryk SO allows to write your own reply as you are writing the question. That's the first time I do it, not sure why I've used "you", I guess because the answer is a valid one regardless of who has asked the question. – elnigno Oct 30 '15 at 08:36
  • 1
    @varocarbas My original question had a disclaimer that was removed after review. It said that I thought it would have been useful information for someone being puzzled after seeing a "weird" sorting. I am working on a computer with Danish locale, however many other settings (including language) are set on US English and I was expecting English sorting. I am not a Dane, I am not used to the Danish sorting and found it peculiar. Other people might incur in a similar problem and find the question/answer useful. – elnigno Oct 30 '15 at 08:40
  • @varocarbas While I mostly agree with your comment on misunderstanding, one has to know that LINQ assumes a particular comparer/parameter, as in the case of the overload of `OrderBy()` that only takes a key selector, which uses the current locale for sorting. Someone might not know that, or forget it. I think it's a legitimate reason for asking a question. Aren't in a way all questions caused by misunderstanding? :) – elnigno Oct 30 '15 at 09:13
  • 2
    Why is it easier to accuse me of dishonesty and artificial upvoting than to give me useful advice on how to improve the question and the answer? I don't know, but I've made some changes that address some of the concerns that have surfaced in the discussion. – elnigno Oct 30 '15 at 09:56
1

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
Serhiy Chupryk
  • 438
  • 2
  • 5
  • 15
  • That's not correct, using your modified list of strings on my computer produces "a, D, z, aaa". – elnigno Oct 30 '15 at 08:35