Reputation: 127
I am trying to sort a list of strings using the German alphabet's phonebook ordering. In the German alphabet sort, the special characters, or umlauts, are represent by the following:
Therefore, the ascending sort order should end up something like this:
I am working in the C# universe and have been using the CultureInfo to create a new string comparer for the sorting. Using this, I get the following order:
Af
List<string> l = new List<string>();
l.Add("Ad");
l.Add("Ä");
l.Add("Af");
var comparer = StringComparer.Create(CultureInfo.CreateSpecificCulture("de"), true);
var x = l.OrderBy(y => y, comparer);
foreach(var outp in x) {
Console.WriteLine(outp);
}
Does anyone know how I could do this with a custom comparer or using an existing culture comparer?
Upvotes: 4
Views: 1523
Reputation: 3276
The German phonebook sort is an alternate sort and can be activated by using "de-DE_phoneb" as the name instead of using "de".
Upvotes: 5
Reputation: 455
You can implement your own comparer class which replaces the umlauts before comparing the two strings:
class CustomStringComparer : IComparer<string>
{
private string ReplaceUmlauts(string germanText)
{
var map = new Dictionary<char, string>() {
{ 'ä', "ae" },
{ 'ö', "oe" },
{ 'ü', "ue" },
{ 'Ä', "Ae" },
{ 'Ö', "Oe" },
{ 'Ü', "Ue" },
{ 'ß', "ss" }
};
var res = germanText.Aggregate(
new StringBuilder(),
(sb, c) => map.TryGetValue(c, out var r) ? sb.Append(r) : sb.Append(c)
).ToString();
return res;
}
public int Compare(string x, string y)
{
var xWithoutUmlauts = ReplaceUmlauts(x);
var yWithoutUmlauts = ReplaceUmlauts(y);
return StringComparer.CurrentCulture.Compare(xWithoutUmlauts, yWithoutUmlauts);
}
}
Code for replacement from here.
Then you can simply create a new instance of CustomStringComparer
and add it as parameter in your .OrderBy
call like this:
var x = l.OrderBy(z => z, new CustomStringComparer());
This will result in the desired output of:
Upvotes: 2