Easy way to reverse each word in a sentence

To reverse a string I use:

new String( word.Reverse().ToArray() )

The Reverse() function is part of LINQ and works because String implements IEnumerable<char>. Its result is another IEnumerable<char> which now needs to be converted to string. You can do that by calling ToArray() which gives a char[] and then pass that into the constructor of string.

So the complete code becomes:

string s="AB CD";
string reversed = String.Join(" ",
    s.Split(' ')
     .Select(word => new String( word.Reverse().ToArray() ) ));

Note that this code doesn't work well with certain unicode features. It has at least two problems:

  1. Unicode characters outside the basic plane need two chars when UTF-16 encoded. Reversing them breaks the encoding. This is relatively easy to fix since surrogates are a simple range of codepoints which will not change in future unicode versions.
  2. Combining character sequences. For example it's possible to create accented characters by writing the base character and a combining accent behind it. This problem is hard to work around since new combining characters can be added with future unicode versions. Zero-width-joiner will cause similar complications.

Well, here's a LINQ solution:

var reversedWords = string.Join(" ",
      str.Split(' ')
         .Select(x => new String(x.Reverse().ToArray())));

If you're using .NET 3.5, you'll need to convert the reversed sequence to an array too:

var reversedWords = string.Join(" ",
      str.Split(' ')
         .Select(x => new String(x.Reverse().ToArray()))
         .ToArray());

In other words:

  • Split on spaces
  • For each word, create a new word by treating the input as a sequence of characters, reverse that sequence, turn the result into an array, and then call the string(char[]) constructor
  • Depending on framework version, call ToArray() on the string sequence, as .NET 4 has more overloads available
  • Call string.Join on the result to put the reversed words back together again.

Note that this way of reversing a string is somewhat cumbersome. It's easy to create an extension method to do it:

// Don't just call it Reverse as otherwise it conflicts with the LINQ version.
public static string ReverseText(this string text)
{
    char[] chars = text.ToCharArray();
    Array.Reverse(chars);
    return new string(chars);
}

Note that this is still "wrong" in various ways - it doesn't cope with combining characters, surrogate pairs etc. It simply reverses the sequence of UTF-16 code units within the original string. Fine for playing around, but you need to understand why it's not a good idea to use it for real data.

Tags:

C#

String