Click here to Skip to main content
Click here to Skip to main content
Alternative Tip

Tagged as

Go to top

How to Toggle String Case in .NET

, 5 Mar 2011
Rate this:
Please Sign up or sign in to vote.
Two more goes and then I'm done. (Wish I could get a job doing this kind of stuff! Wish I could get a job!)This is similar to my previous attempt but Reflector showed how ToLower() and ToUpper() are implemented and we can save some time by caching the CurrentCulture.TextInfo which saves...
Two more goes and then I'm done. (Wish I could get a job doing this kind of stuff! Wish I could get a job!)
 
This is similar to my previous attempt but Reflector showed how ToLower() and ToUpper() are implemented and we can save some time by caching the CurrentCulture.TextInfo which saves about 14%:
 
public static string ToggleCase_SimmoTech(string s)
{
    char[] chs = s.ToCharArray();
    var currentCultureTextInfo = CultureInfo.CurrentCulture.TextInfo;
 
    for (var i = 0; i < s.Length; ++i)
    {
        char ch = chs[i];
 
        if (ch <= 0xff)
        {
            if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
                (ch >= 0xc0 && ch <= 0xde && ch != 0xd7) || (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7))
            {
                chs[i] = (char) (ch ^ 0x20);
            }
 
            continue;
        }
 
        switch (char.GetUnicodeCategory(ch))
        {
            case UnicodeCategory.UppercaseLetter:
                chs[i] = currentCultureTextInfo.ToLower(ch);
                break;
 
            case UnicodeCategory.LowercaseLetter:
                chs[i] = currentCultureTextInfo.ToUpper(ch);
                break;
        }
    }
 
    return (new string(chs));
}
 
and finally, my fastest (and last) effort:
 
To save checking the character ranges which are toggleable, we can use a lookup table like this:
 
static readonly bool[] ToggleableLatinChars = new[]
 {
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
      true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false,
      false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
      true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
      true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
      true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, false,
      true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
      true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, false
  };
 
public static string ToggleCase_SimmoTech2(string s)
{
    char[] chs = s.ToCharArray();
 
    var currentCultureTextInfo = CultureInfo.CurrentCulture.TextInfo;
 
    for (var i = 0; i < s.Length; ++i)
    {
        char ch = chs[i];
 
        if (ch <= 0xff)
        {
            if (ToggleableLatinChars[(byte) ch])
            {
                chs[i] = (char) (ch ^ 0x20);
            }
 
            continue;
        }
 
        switch (char.GetUnicodeCategory(ch))
        {
            case UnicodeCategory.UppercaseLetter:
                chs[i] = currentCultureTextInfo.ToLower(ch);
                break;
 
            case UnicodeCategory.LowercaseLetter:
                chs[i] = currentCultureTextInfo.ToUpper(ch);
                break;
        }
    }
 
    return (new string(chs));
}
 
This saves 2% or 3% more, but with the extra data required I wouldn't bother unless it was an absolutely speed-critical algorithm.
 
Cheers,
Simon

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

SimmoTech
Software Developer (Senior) Hunton Information Systems Ltd.
United Kingdom United Kingdom
Simon Hewitt is a freelance IT consultant and is MD of Hunton Information Systems Ltd.
 
He is currently looking for contract work in London.
 
He is happily married to Karen (originally from Florida, US), has a lovely daughter Bailey, and they live in Kings Langley, Hertfordshire, UK.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 6 Mar 2011
Article Copyright 2011 by SimmoTech
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid