Title Case a Sentence Algorithm challenge - my solution

Hi guys,

My first post here.

I had been spending (two) hours trying to figure this one out after learning what I can and can’t do with arrays.

This is what I did- it’s not the most efficient but it’s what made sense logically, plus i kind of mixed up es6 in there as I was wondering if that stopped my code from working.

  • Convert String to lowercase and store in an array.
  • Initialise an empty array.
  • for loop that runs the length of the String passed which copies elements into new array by:
  1. checking if it’s the first element of the array and capitalises this, otherwise copies over the array
  2. If the array element is preceded by an empty space capitalises said element (first letters of words are preceded by empty spaces)

Solution below (hidden)

Summary
function titleCase(str) {

var lowerCase=str.toLowerCase(); //convert string to lower case

var b=lowerCase.split(""); //split string into


var arr=[]; 						//initialised array


for(let i=0;i < b.length; i++){ 			//for loop for length of string




arr.push(b[i]); 				//maps element in b to arr

	if (i == 0){ 					// checks first element and capitalise, replacing lowercase element
					arr.pop(); 			//remove lowercase
				arr.push(b[i].toUpperCase()); 


}

		if(b[i-1] == " ")
		
		{ 					//check to see if previous element is empty string
					arr.pop();
				arr.push(b[i].toUpperCase()); //remove present element and replace with capitalised



		}


}

return arr.join(""); //join array so it's a string

}



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

Without even reading your code the first syntax error I see is:

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

You have an extra ‘;’ in your function evocation.

Check that in your editor you have the actual character you want instead of &amp;lt;

Bonus point if you can make it more efficient. You don’t need to separete the string in an array made of all the characters and then loop over each character, you can make a code that need a lot less steps

There’s a few more issues going on here.

Look at your for loop on first loop.

arr = [];
b = [‘i’,’’’, ‘m’, ’ ', ‘a’, …]

So first you loop through each letter.

let i = 0;

If you look at your 2nd if condition you will have b[i - 1] which will be b[0 -1] which will give you unexpected results.

Also., why add the first character to arr only to remove it again?

Always use === and never == in javascript.

that’s not true, there are situations in which a loose comparison is useful. And situations in which you must use the other one. But it is situational.

Then you should convert the other value leahleen. Always use it.

That is not an empty string, that is a space. An empty string is "" (see? empty) and it is different than a space.

Why add this extra step anyway? Can’t you make the check before adding the character to the array?
Do you really need to loop over all characters? Is there an other way in which you can identify the first character of each word?

Don’t take my word for it.

Almost 6k upvotes and Douglas Crockford’s excellent JavaScript: The Good Parts, suggests same thing.

Using == isn’t there already coercion?

If I have to compare a number from a string to a variable, using == will need less code written and improve readability. The first YDKJS JavaScript makes a good point on the use of the equality operators

[broken link]

I certainly don’t take your word for it.

I also have a book! You Don’t Know JavaScript - Chapter 2: Into JavaScript

Much prefer this view. It’s there, why don’t use it?

If I have to compare a number from a string to a variable, using == will need less code written and improve readability.

let myVar = “3”;
Number(myVar) === 3 // how is this not readable?

Hi I’ve re-uploaded it.

For some reason when copying and pasting my solution some characters were eoncoded (quotes).Updated code should read better now

I think it’s the encoding. I tried to convert some of them back to original form. I’ve tried to re-add the code again

Hey,
Thanks for your feedback.

Point taken about b[-1], although wouldn’t it not do anything in this case as you can’t have that index. I guess I could add an extra condition to check that b is at least 1.

What happened is that when adding the element was that it was adding in lower case. So i removed the lower case and replaced with upper case.

What I could’ve done in hindsight is two ifs statement

  • first checking if the index is 0 to capitalise
  • then checking the first letter of each word to categorise (I used checking to see if the previous element was a " ")
  • if neither is the case, then copying over the element in the exact case

Didn’t mean empty, but essentially checking if the previous index has a space only. You are right that I could’ve done two ifs. (or even one as below)

  • First to check if it’s the first index, then to check if the previous element is a space and not 0
    e.g. if(b[i-1]== " " && i>0 || i === 0)

If neither condition is met then push the case in the original array

I couldn’t think of another way to add the first character to each word at the time.

THanks either way

You could divide the string into words (str.split(' ')), in this way your loop would be much more shorter, and use replace(). Try to solve in this way too, just for practice.

I couldn’t think of another way to add the first character to each word at the time.

I don’t know what challenge you’re doing,. but if you’re looking to capitalize every first letter of each word then here’s an example.

var sentence = "teapot is my favorite";
var newWord = sentence.split(' ').map(function(word){
    return word[0].toUpperCase() + word.slice(1);
}).join(' ');

and es6:

const sentence = "teapot is my favorite";
const newWord = sentence.split(' ').map((word) => word[0].toUpperCase() + word.slice(1)).join(' ');

console.log(newWord); // Teapot Is My Favorite