Title Casing a Sentence - Basic Algorithms

Hi guys,

After hitting the basic algorithms, I’ve been getting pretty bogged down and am having to stare at each one for quite a long time. I think i’ve possibly raced through the basic JS and OOJS sections too quickly to take it all in and understand it properly, as this stuff doesn’t seem intuitive to me yet, which is frustrating.

Anyway - I’m trying to output a whole sentence with the first word capitalised… I’ve managed to get the first word in the sentence output with a capital, but I can’t get my head around the code that’s needed to loop through and add the next word to the variable so that you get the full sentence… Can anyone give me a pointer?

Also I realise my code can probably be condensed a lot…

Thanks!!

function titleCase(str) {

var lcase = str.toLowerCase();
  var splstr = lcase.split(' ');
  
  // cap each letter and extract
  for (var i=0; i < splstr.length; i++) {
  var capChar = splstr[i].charAt(0).toUpperCase(); 
  var subarr = splstr[i].split('');
    // now replace the first index of each subarr with capChar
   var finalsub = subarr.splice(0,1,capChar); 
  // now join the subarr back together 
var subjoin = subarr.join('');
    return subjoin;

}

}

Don’t get frustrated. This type of thing takes a certain way of thinking. It comes easily to some, it takes a little more work for others. But you’ll get it if you keep at it. The more of these things you do, the more little tricks you’ll pick up. It gets easier

As to what you have so far, I think you’re declaring more variables than you need. Also, you have a return statement in your loop, meaning that the first time it gets there, it’s going to exit the function. In theory, that is where you should save your title-cased value to whatever you want.

I think I started out similarly to what you are doing. But inside the loop I just added an uppercased first char to the sliced off rest of the string and assigned that back to same slot in the array of strings. Then at the end of the function, I join them together and return them.

1 Like

Thanks for the encouragement Kevin.

That’s what I had tried in my code, I think, though after joining together each broken up word, I was having trouble adding them into one sentence with the loop, though I think my last line of code now solves that.

The issue I have now is that I get the desired output but it’s saying undefined before it, i.e. “undefined I’m A Little Tea Pot”, and it’s also saying the variable I’m declaring after the return is being used out of scope - even though i declared it with “var” meaning it should be global…?

My new “working” code is below, if anyone can offer any insight:-

function titleCase(str) {

var splstr = str.toLowerCase().split(’ ');

// cap each letter and extract
for (var i=0; i < splstr.length; i++) {
var capChar = splstr[i].charAt(0).toUpperCase();
var subarr = splstr[i].split(’’);
// now replace the first index of each subarr with capChar
var finalsub = subarr.splice(0,1,capChar);
// now join the subarr back together and add each word to make the full sentence
var subjoin = subjoin + " " + subarr.join(’’);

}

return subjoin;}

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

My code works slightly better now… but my output has a space infront of the first word, which i can’t seem to remove without taking away the spaces between each word…

var subjoin = "";

function titleCase(str) {

  var splstr = str.toLowerCase().split(' ');
  
  // cap each letter and extract
  for (var i=0; i < splstr.length; i++) {
  var capChar = splstr[i].charAt(0).toUpperCase(); 
  var subarr = splstr[i].split('');
    // now replace the first index of each subarr with capChar
   var finalsub = subarr.splice(0,1,capChar); 
  // now join the subarr back together 
 subjoin = subjoin + " " + subarr.join('');
    
}
  
return subjoin;}


titleCase("sHoRt AnD sToUt");

subjoin = subjoin + " " + subarr.join('');

You are concatenating a space character in front of every join(), including the very first word.

So the question to ask is, how to add spaces only between the words?

Look at your split() function and notice how you can declare HOW you want to split an array. Perhaps there is similar functionality for the join() function?

The only way to be sure what a predefined function does is to look at the source documentation.

Here’s is info on the join() function:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join?v=example

1 Like

Since I see in the other thread I see you have a working solution, I am comfortable showing you another, simpler way.

function titleCase(str) {
  //put sentence to lower case and split into words
  var splStr = str.toLowerCase().split(' ');

  // iterate through each word
  for (var i=0; i < splStr.length; i++) {
    // take the first letter of each word(put to uppercase) and
    // add it to the rest of the word and assign it back into 
    // that word's array slot, basically replacing it with 
    // the capitalized version.
    splStr[i] = splStr[i].charAt(0).toUpperCase() + splStr[i].slice(1); 
  }
  // rejoin the array of words back together
  return splStr.join(" ");
}

That, to me, is easier to read and more clear as to what is happening. There are other refinements we could do, but this is fine for now.

Looking at your second code snippet, I would make a few comments:

subjoin is declared globally. I would not do that. SInce it is only needed inside the function, that is where it should be declared. It may not matter on a small thing like this, but it is a good habit to get into.

Use the JS variable name convention of small camel case. names should have each word after the first capitalized. so subjoin should be subJoin, etc. It technically doesn’t matter, but it makes it more readable and it will seem strange to other JS coders if you don’t.

There are little tricks you can learn, for example subjoin = subjoin + " " + subarr.join(’’); could have been subjoin += " " + subarr.join(’’)

And watch the formatting, like indenting and what line things are on. For example, return subjoin;} - that curly brace should be on the next line and that and the previous couple of lines should be indented. No, it doesn’t stop it from working, but it does make it more difficult to read - when I first looked, I thought that return was outside the function. A helpful tip - in most code editors, once you get everything on the correct lines, if you select it all and do a shift-tab, it will auto format for you. But get into the habit of formatting as you go.

1 Like

Hey, thanks again for your response.

Just going back to the code above, I have one perhaps silly query:-

splStr[i] = splStr[i].charAt(0).toUpperCase() + splStr[i].slice(1);

I get what you’re doing here, but… the first half of that equation gives the capitalized letter from the word, and adds it to splStr[i].slice(1). Does that second part with the slice not slice the whole word? Meaning that the result of having “example” in there, would output “Eexample”? I don’t quite get how the slice function is working here.

That would be true if I gave slice no parameter, but I sent it a 1 telling it that I want it to start with the second character (remembering that it’s zero indexed.) The function slice has the form of str.slice(beginIndex[, endIndex]).

So the following code…

var str = "example";

console.log( str.slice() ); // example
console.log( str.slice(0) ); // example
console.log( str.slice(1) ); // xample
console.log( str.slice(2,4) ); // am

Array has a similar function. They’re very useful.

Hope this helps.

1 Like

Sorry, that’s pretty basic - I get it now. Should have read through the slice documentation properly first! Thanks!