0

I am trying to capitalize the first letter of every word in the string. I wanted to do it in 3 steps:

  1. Turn string into an array using .split().
  2. Create a loop and change the first letter in every word by addressing it with an array index.
  3. Finally I wanted to use .join to put everything back in a string.

But something went wrong and I can't go to the 3rd step. The for loop does change the letter to uppercase, but when I return the variable cap it only returns the first capitalized letter of the last word in the string. In the example it's P(the last word is pot), if I erase pot it returns T(because tea becomes the last word).

Why doesn't the cap variable return the whole array with capitalized first letters? What am I missing?

Here's the code:

function titleCase(str) {
  var arr = str.split(" ");
  for (i = 0; i < arr.length; i++) {
    var cap = arr[i][0].toUpperCase();
  }
  return cap;
}

titleCase("I'm a little tea pot");
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
Igor Schekotihin
  • 177
  • 1
  • 12
  • 2
    Possible duplicate of [Convert string to title case with JavaScript](http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript) – Talya S Feb 21 '17 at 19:59
  • 1
    You're setting `var cap = "the first letter of the current word"`, so once the loop is complete, `cap` will be set to the first letter of the last word. – Tyler Roper Feb 21 '17 at 20:02
  • That is alot of overhead for something you can do easily in CSS: .myclass { text-transform:capitalize; } – Korgrue Feb 21 '17 at 20:03

6 Answers6

3

That's because you're just returning the cap variable which will contain the last words first letter to upper case (left by last iteration).

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

    for (i = 0; i < arr.length; i++) {
        var word = arr[i];
        // capitalized first letter + rest of the word
        var capitalizedWord = word[0].toUpperCase() + word.slice(1);

        arr[i] = capitalizedWord; // replace the uncapitalized word with capitalized one
    }

    return arr.join(" "); // join with spaces to make it a sentence again
}

titleCase("I'm a little tea pot");
Luka Kvavilashvili
  • 1,309
  • 10
  • 13
1

It's because cap is only a variable so as you loop through your words it keeps getting overwritten by the first letter of the next word. Make it an array or concatenate the next letter onto it.

mysticalstick
  • 2,479
  • 5
  • 16
  • 21
0

I think this is the answer:

const capitalizeFirst = data => data.replace(/[\w']+/g, x => x[0].toUpperCase() + x.slice(1).toLowerCase())

console.log(capitalizeFirst("I'm a little tea pot"))
Maciej Kozieja
  • 1,812
  • 1
  • 13
  • 32
0

You are overriding the variable cap in each iteration. Your code slightly modified:

function titleCase(str) {
  var arr = str.split(" ");
  var cap = "";
  for (i = 0; i < arr.length; i++) {
    if (i != arr.length - 1) {
      cap += arr[i][0].toUpperCase() + arr[i].substr(1) + " ";
    } else {
      cap += arr[i][0].toUpperCase() + arr[i].substr(1);
    }
  }
  return cap;
}

titleCase("I'm a little tea pot");
Yaman Jain
  • 1,254
  • 11
  • 16
0

You are committing a cardinal sin of Javascript! Don't ever declare variables inside of a loop.

function titleCase(str) {
  var cap;
  var arr = str.split(" ");
  for (i = 0; i < arr.length; i++) {
    cap = arr[i][0].toUpperCase();
  }
  return cap;
}

Would be the proper way to type what you have written.

When your for loop iterates in your example, it re-declares the variable each time which causes some bad things to happen. In my example, it is re-defined each time but only declared once.

However, this is all still incorrect for your problem. This will only give you the single letter when you want the entire string. Try something like this

function titleCase(str) {
  var arr = str.split(" ");
  var wordToCap;
  var capWord;
  var capArray = [];
  for (var i = 0; i < arr.length; i++) {
    wordToCap = arr[i];
    capWord = wordToCap.charAt(0).toUpperCase() + wordToCap.substring(1);
    capArray.push(capWord);
  }
  return capArray.join(" ");
}

There are much more elegant ways of solving this problem, but hopefully all the steps broken down here will help you understand what your loop is doing and should be doing.

Good luck!

0

ES2015 solution:

const titleCase = str => 
  str.split(' ').map(word =>
    word.charAt(0).toUpperCase() + word.slice(1)
  ).join(' ');

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

Working example: https://jsfiddle.net/ecdkxrjd/

dominik791
  • 692
  • 6
  • 17