Proper Casing Of Proper Names

I was consuming an external API that was returning people’s first names.  The problem was that the names were coming back all caps (eg: “GILLIGAN”).  I wanted to convert that into the proper case (eg: “Gillian”).  In the past, I would call ToLower() of the string and then take the first character of a substring and make it Upper().  To protect myself in case there was several words in the name(eg: MARY ANN), I would also need to split on any spaces and loop through the array doing my Upper/Lower functions.  The code would look something like this:

static void WrongWay(String name)
{
    String tempWord = String.Empty;
    String firstLetter = String.Empty;
    String restOfWord = String.Empty;
    StringBuilder stringBuilder = new StringBuilder();

    String[] splitName = name.Split(' ');
    foreach (String word in splitName)
    {
        tempWord = word.ToLower();
        firstLetter = tempWord.Substring(0, 1);
        firstLetter = firstLetter.ToUpper();
        restOfWord = tempWord.Substring(1, tempWord.Length-1);
        stringBuilder.Append(firstLetter);
        stringBuilder.Append(restOfWord);
    }
    Console.WriteLine(String.Format("Was = {0} Now = {1}", name, stringBuilder.ToString()));
}

And the output looks like this:

image

I hate this solution for a couple of reasons:

  • It smells like Kludgy code
  • It is Kludgy code
  • It does not account for people with single letter names
  • It does not account for internationalism and different languages that use different glyphs

I thought to myself – there must be a better way and since Microsoft has lots of smart people, they might have done something like this already.

My first stop was the String.ToLower() overload.  I pumped in the different cultures (Current and CurrentUI):

static void WriteNames(String name)
{
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
    CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;

    Console.WriteLine(String.Format("ToLower = {0}",name.ToLower()));
    Console.WriteLine(String.Format("ToUpperWithCurrentCulture = {0}", name.ToLower(currentCulture)));
    Console.WriteLine(String.Format("ToUpperWithCurrentUICulture = {0}", name.ToLower(currentUICulture)));
}

Alas, it did not work:

image

ToUpper() had the same (non) effect.

I then thought “Hey, maybe I should check MSDN or Stackoverflow”.  Sure enough, I ran into this page.  Without reading the entire page (who does that?)  I jammed in this line of code,

Console.WriteLine(String.Format("currentCulture.TextInfo.ToTitleCase using Upper = {0}", 
    currentCulture.TextInfo.ToTitleCase(name)));

but I got the same result:

image

 

I then went back and read the entire MSDN page.  I changed my code to this (note the ToLower())

Console.WriteLine(String.Format("currentCulture.TextInfo.ToTitleCase using Lower = {0}",
    currentCulture.TextInfo.ToTitleCase(name.ToLower())));

Sure enough:

image

Not only that, it works for multiple words:

image

Not only that, it handles middle initials!

image

Alas, it does not handle suffixes:

image

Still, that function gives you plenty out of the box.  I am very excited (OK, mildly excited) about this new find….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: