65.9K
CodeProject is changing. Read more.
Home

Extension Methods to Reverse a String and StringBuilder Object

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (4 votes)

Jan 1, 2011

CPOL

2 min read

viewsIcon

33251

We're up to .NET 4 and MS *still* hasn't given us this simple functionality.

While writing a new article, I was fiddling around with some really old code, and stumbled across a method I wrote four years ago. It dealt with several methods for reversing a string, and it lived in a "global" class that contains a lot of little methods that makes my day-to-day development efforts a little easier.

Well, never one to let an opportunity to possibly screw up some otherwise working code go to waste, I decided to muck around by making the existing method an extension method, and adding a second one to handle StringBuilder objects. The existing string object method goes like this:

public static class ExtensionMethods
{
    public static string Reverse(this string text)
    {
        if (text.Length > 1)
        {
            int pivotPos = text.Length / 2;
            for (int i = 0; i < pivotPos; i++)
            {
                text = text.Insert(text.Length - i, text.Substring(i, 1)).Remove(i, 1);
                text = text.Insert(i, text.Substring
                       (text.Length - (i + 2), 1)).Remove(text.Length - (i + 1), 1);
            }
            return text;
        }
    }
}

The whole point was to perform the operation in as little time as possible, and the best way to do that (as far as I could see) was to determine how many character swaps had to be performed (text.Length / 2), and then simply swap character on each end of the string until it met in the middle. The really cool thing about this is that it works for strings that have even AND odd lengths because in the event of an odd-length string, the middle character doesn't need to change position. In our case, the division operation rounds down to the nearest whole integer value, which is perfect for what we want to do.

For the StringBuilder object, I wanted to preserve its immutable nature, which meant I couldn't just use its ToString() method, and call the previously described method, although that's certainly a viable and easy way to accomplish the same goal. Here's the code:

public static void Reverse(this StringBuilder text)
{
    if (text.Length > 1)
    {
        int pivotPos = text.Length / 2;
        for (int i = 0; i < pivotPos; i++)
        {
            int iRight     = text.Length - (i + 1);
            char rightChar = text[i];
            char leftChar  = text[iRight];
            text[i]        = leftChar;
            text[iRight]   = rightChar;
        }
    }
}

In the code above, we simply determine what positions we're at (i and iRight), retrieve the characters at those positions (rightChar, and leftChar), and put them in the appropriate location in the StringBuilder's array. (Yes, I could have done the position math in the two places I needed it, but I wanted to be able to verify (in the debugger) that the values were what I wanted.

Usage

// start with text being "testing"
string text = "testing";
// the following line will cause test to be "gnitset"
text = text.Reverse();

// instantiate test with the current value of text ("gnitset")
StringBuilder test = new StringBuilder(text);
// the following line will cause test to be "testing"
test.Reverse();

I know, this ain't rocket science code, and you probably won't need it very often, but it's pretty handy to have around if you ever need to do this kind of thing.

NOTE: I want to point out that for the string method, you could always do something like this:

public static string Reverse(this string text)
{
    StringBuilder temp = new StringBuilder(text);
    return temp.Reverse().ToString();
}

...which would be much more efficient in terms of memory use than doing this:

public static void Reverse(this StringBuilder text)
{
    string temp = text.ToString().Reverse();
    text.Replace(text.ToString(), temp);
}