Title Case a Sentence with nested Arrays [SOLVED]

Howdy folks,

So, I’m in the Basic Algorithms section working on the ‘Title Case a Sentence’ project.

I decided to take a nested For Loop approach.

The steps in my brain go like this;

  1. Split the string into an array of words, make sure all characters are lower case. (stringArray)
  2. Split these words in to arrays of letters, so they become nested arrays of the stringArray (wordArray)
  3. Upper case the first letter of each word based on its index in wordArray.
  4. Join the words back together, now with the first letter capitalized.
  5. Join the string back together with a space between each word.

In its present state, it seems that my For Loops are being completely skipped over in the function and I can’t figure out why. That’s the part I could use help with at the moment.

Here’s the code:

function titleCase(str) {
  var stringArray = str.toLowerCase().split(' ');
  
  for (i = 0; i < stringArray.length; i++) {
    var wordArray = stringArray[i].split('');
    
    for (j = 0; j < wordArray.length; j++) {
      wordArray[j][0].toUpperCase();
      wordArray.join('');
    }
  }
  
  var titleCaseString = stringArray.join(' ');
  
  return titleCaseString;
}

titleCase("I'm a little tea pot");

Well instead of creating two for loops and arrays you could just have one for loop and one array and use the string.replace and string.charAt function. You could just use the first for loop and instead of trying to split them again use those two functions to replace the first letter of the word and then join it all again.

Thanks @the702guy, I did see solutions using that approach in some examples. While it’s definitely useful and I would likely take that approach in a real-world example, now that I’ve seen those methods used. I’ll agree it’s a more elegant and concise approach. But I felt like I wouldn’t really have learned much just copying another coder’s solution. I had’t seen one quite like the one I’m trying here, so I thought I’d have a go at it.

So I figured it out using two for loops like you had. I have a solution if you would like me to post it. If you would like to figure it out yourself here are a few hints:

-Try defining your variables first.
-You will need to use methods such as push, shift, and unshift
-Your for loops will need to be separate, not nested into each other

Like I said I made a solution that works and I have already tested it. If you would like me to post it let me know. I hope these hints get you in the right direction.

EDIT: Also your wordArray variable is running the for loop and resulting in only the last word in the array actually being split up, not every word. You will need to use one of the methods I mentioned above to make arrays of those split words nested in to one array.

Thanks so much for the hints! Much appreciated, @the702guy!

I’d like to have a go at figuring this out from your hints first before asking for more help. I’ll let you know the results hopefully soon.

No worries man, I hope you get it! I have the solution saved in a pen so just let me know if you would like to see it, I’ll post it here.

So I did finally come up with a solution I’m satisfied with this morning (got some help from a work colleague). It ended up only requiring one loop, however.

I was basically trying to create a nested array that allowed me to use toUpperCase() on the zero index of each word. I was thinking I would need two loops to do this, but it turned out not to be the case. I didn’t even need to use push, shift or unshift methods, so I feel like this turned out to be a pretty clean approach to the problem.

I also changed the nomenclature a little bit;
stringArray (array of words made from a string) has been changed to wordArray (array of words).
wordArray (array of characters made from words) has been changed to charArray (array of characters).

Seemed to make more intuitive sense after I had been looking at other examples for this problem.

I would love to see your two loop function, @the702guy, now that I was able to get through this.

Here’s mine:


SPOILER ALERT

function titleCase(str) {
  var wordArray = str.toLowerCase().split(' '); // changes string to all lower case and separates string into array of words
  // console.log(stringArray);
  var charArray = []; // creates array to be nested in upcoming loop
  
  for (i = 0; i < wordArray.length; i++) {
    charArray = wordArray[i].split(''); // creates nested array of individual characters
    // console.log(charArray[0].toUpperCase());
    charArray[0] = charArray[0].toUpperCase(); // changes first value of each nested array to upper case character
    // console.log(charArray.join(''));
    wordArray[i] = charArray.join(''); // joins nested character array back into word array
  }
  
  str = wordArray.join(' '); // joins word array back into string, with spaces separating each word
  
  // console.log(str);
  return str;
}

titleCase("I'm a little tea pot");

Bloody 'ell, @rmdawson71, I’m impressed! Especially with your first example, all on one line.

I think I’ll go ahead and mark this problem as [solved]. Thanks @rmdawson71 and @the702guy for your input.

@the702guy, I’d still love to see your two loop solution. I appreciated your advice and your dedication to making that scenario work. It amazes me that there are so many ways to solve the same problem with JavaScript, and programming languages in general.

Sorry for such a late reply, I have been very busy the last week or so I haven’t been able to work on this stuff much. Here is my two for loop solution that passes all the tests.

[spoiler]function titleCase(str){
var stringArray = str.toLowerCase().split(’ ');
var wordArray = [];
var finalArray = [];

for (i = 0; i < stringArray.length; i++){
wordArray.push(stringArray[i].split(’’));
}

for (j = 0; j < wordArray.length; j++){
var toCap = wordArray[j][0].toUpperCase();
wordArray[j].shift();
wordArray[j].unshift(toCap);
finalArray.push(wordArray[j].join(’’));
}

return (finalArray.join(’ '));
}
titleCase(“This iS a tESt seNTenCe”);[/spoiler]

1 Like

Awesome! Thanks for posting, @the702guy.

Hi @janusoo,
I was playing with your solution & you don’t even need to create the empty array (line 3). See below.
Thx!

function titleCase(str) {
var wordsArray = str.toLowerCase().split(" ");

// var charsArray = [];

for (i = 0; i < wordsArray.length; i++) {
charsArray = wordsArray[i].split("");
charsArray[0] = charsArray[0].toUpperCase();
wordsArray[i] = charsArray.join("");
}

str = wordsArray.join(" ");
return str;

}

titleCase(“I’m a little tea pot”);