C# Compare strings with umlaut strange results

Viewed 238

I use string.Compare(strA, strB, true, CultureInfo.CurrentCulture); and dont unterstand the result. CurrentCulture is "de-DE".

string.Compare( "o", "ö", true, CultureInfo.CurrentCulture) // result: -1 
string.Compare( "d", "f", true, CultureInfo.CurrentCulture) // result: -1 
string.Compare( "dx", "fa", true, CultureInfo.CurrentCulture) // result: -1 
string.Compare( "ox", "öa", true, CultureInfo.CurrentCulture) // result: 1 
string.Compare( "oa", "öx", true, CultureInfo.CurrentCulture) // result: -1

Why the result depends on the second letter to get different results at last 2 lines? If o ist first and ö is next should line 4 not also return -1? Can someone explain this?

To explain why i have problems with this Compare some code:

class Program
    {
        public class ComparerB : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                return string.CompareOrdinal(x, y);
            }
        }

        public class ComparerA : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                return string.Compare(x, y, true, CultureInfo.CurrentCulture);
            }
        }

        static void Main(string[] args)
        {
            List<string> list = new List<string>();
            list.Add("Update");
            list.Add("Ö3 Greatest Hits");
            list.Add("Dont sleep");
            list.Add("Friends");
            list.Add("Dart vadder");
            list.Add("Family");
            list.Add("Oxfort");
            list.Add("Ödipus");
            list.Add("Oasis");
            list.Add("Österreich");
            list.Add("Panda");

            list.Sort(new ComparerA());
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine();
            list.Sort(new ComparerB());
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
        }
    }

Using ComparerA the result is(mixed Ö and O):

Dart vadder
Dont sleep
Family
Friends
Ö3 Greatest Hits
Oasis
Ödipus
Österreich
Oxfort
Panda
Update

Using ComparerB the result is(Ö at end of list):

Dart vadder
Dont sleep
Family
Friends
Oasis
Oxfort
Panda
Update
Ö3 Greatest Hits
Ödipus
Österreich

But what i need is this(Ö after O):

Dart vadder
Dont sleep
Family
Friends
Oasis
Oxfort
Ö3 Greatest Hits
Ödipus
Österreich
Panda
Update

2 Answers

I think that in the German alphabet sort the special character ö is internally represented by oe.

So string.Compare( "o", "ö", true, System.Globalization.CultureInfo.CurrentCulture); is equivalent to string.Compare( "o", "oe", true, System.Globalization.CultureInfo.CurrentCulture);.

And string.Compare( "ox", "öa", true, System.Globalization.CultureInfo.CurrentCulture); is equivalent to string.Compare( "ox", "oea", true, System.Globalization.CultureInfo.CurrentCulture);. Then the result 1 makes sense.

In your Comparer A, you have the code

return string.Compare(x, y, true, CultureInfo.CurrentCulture);

which means you are using the CurrentCulture which is German as I believe, so the German alphabet as I noticed on the internet are in the following sequence

A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, Ä, Ö, Ü, ß

So, the sorting will be accordingly, so what you currently get is the right I believe but if you still need to do as you wish and you are open to using another CultureInfo where the sequence of O, Ö is just behind each other like Turkish "tr-TR", then the code should be this:

return string.Compare(x, y, true, new CultureInfo("tr-TR"));

which is giving you the following result:

Dart vadder
Dont sleep
Family
Friends
Oasis
Oxfort
Ö3 Greatest Hits
Ödipus
Österreich
Panda
Update

The other option is to develop your custom sorting algorithm and function that consider any sequence of characters you like.

Related