2019-09-11
Alphabetical order, Array.Sort() doesn't work well
stackoverflow
Question

I have problem with alphabetical order. Array.Sort() doesn't work well in my case.

string str = "AaBbCc";
char[] arr = second.ToCharArray();
Array.Sort(arr);

// Output: ABCabc
// I need: AaBbCc

Any ideas?

Answer
1

You can achieve what you're looking for with LINQ.

First, we need to break your characters up into a sequence of single character strings. We can do that with select.

str.Select(x => x.ToString())

Okay, now we want to order this list. The default sort for strings is word sort, which would order it like aAbBcC. Since you want to get the capitals first, we'll use the OrdinalIgnoreCase comparer, which will group our characters up.

   .OrderBy(x => x, StringComparer.OrdinalIgnoreCase)

Okay, so we've now grouped our characters. We'll now want to sort those groups ordinally to get the capitals to come first, using ThenBy.

   .ThenBy(x => x, StringComparer.Ordinal)

Finally, we can turn it into an array.

   .ToArray();

Bringing it together, we get the following:

var res = str.Select(x => x.ToString())
             .OrderBy(x => x, StringComparer.OrdinalIgnoreCase)
             .ThenBy(x => x, StringComparer.Ordinal)
             .ToArray();

Which gives us an array that looks like this: ["A","a","B","b","C","c"]

At this point, as @dvo has pointed out, we can turn it back into a single string with a call to String.Join, like so:

var resStr = string.Join("", res);

As @RufusL points out, we can do more for this query. Since we know we ultimately want a string, we can skip the ToArray call entirely and stick with the IOrderedEnumerable<string>.

var res = str.Select(x => x.ToString())
             .OrderBy(x => x, StringComparer.OrdinalIgnoreCase)
             .ThenBy(x => x, StringComparer.Ordinal);

Since we aren't joining anything with strings we can use string.Concat instead of string.Join.

var resStr = string.Concat(res);
Alphabetical order, Array.Sort() doesn't work well
See more ...