skip to Main Content

I try to make this excercise:
Return the provided string with the first letter of each word capitalized. Make sure the rest of the word is in lower case.
My code works, but I don’t know why adding i++ in first if fixing it. How does this code work?

My code:


function titleCase(str) {
  const toLowerC = str.toLowerCase();
  let word = ""
  for (let i = 0; i < toLowerC.length; i++) {
    
    if (i === 0) {
      word += toLowerC[i].toUpperCase();
      i++  **//  Why does adding i++ make the code work? I was thinking that this code should work like this: else is triggered when the first and second if are false..."
**
    }
    if (toLowerC[i] === " ") {
      word += toLowerC[i] + toLowerC[i + 1].toUpperCase();
      i++
    } else {
      word += toLowerC[i]
    }
  }
  return word;
}

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

I’ve tried OpenAI, but it gets confused, or maybe I’m phrasing my questions incorrectly.
I’ve seen many other ways to complete this excercise thats not my point to make my code better.

2

Answers


  1. The algorithm is easier to understand if we introduce a boolean variable beginningOfWord, which is true

    • at the beginning of the for loop and
    • whenever the previous character is a space.

    (Note if the string contains two consecutive spaces, the algorithm tries to uppercase the second, but this simply has no effect.)

    function titleCase(str) {
      const toLowerC = str.toLowerCase();
      let word = ""
      for (let i = 0, beginningOfWord = true; i < toLowerC.length; i++) {
        if (beginningOfWord)
          word += toLowerC[i].toUpperCase();
        else
          word += toLowerC[i];
        if (toLowerC[i] === " ")
          beginningOfWord = true;
        else
          beginningOfWord = false;
      }
      return word;
    }
    
    console.log(titleCase("I'm a  little tea pot"));
    Login or Signup to reply.
  2. The i++ is necessary in your case because you have two separate if-statements following one another.

    if (i === 0) { // <--- If statement 1
      ...
    }
    
    if (toLowerC[i] === " ") { // <--- If statement 2
      ...
    } else {
      ...
    }
    

    The first if-statement handles the case for when you’re on the first letter. When that runs, you’ve handled the first letter (ie, index 0), however, since the next if statement that follows it isn’t an else if, but rather its own if, you’ll now be updating word again with the current letter, regardless of if it goes into the if or else branch of the second if-statement, as in both cases you’re performing word += toLowerC[i]. That’s why if you perform i++ in your first if-statement, the second if-statement that runs will be checking the next letter, and so you won’t be trying to handle the first one twice as you would be without the i++.

    It might be easier to change your second if to an else if, as well as change the condition to check if the previous character was a space to determine if the current character should be made uppercase, this way, you’re only handling one character at a time:

    function titleCase(str) {
      const toLowerC = str.toLowerCase();
      let word = ""
      for (let i = 0; i < toLowerC.length; i++) {
        if (i === 0) {
          word += toLowerC[i].toUpperCase();
        } else if (toLowerC[i-1] === " ") { // the above branch can be removed and rolled into this one if `i === 0 || <current conditin>` is used instead 
          word += toLowerC[i].toUpperCase();
        } else {
          word += toLowerC[i]
        }
      }
      return word;
    }
    
    console.log(titleCase("I'm a little tea pot"));

    I know you mentioned that you’re not after alternatives, but it might help future readers or give you some more insights. I would most likely use a regular expression to match the characters that need uppercasing and then use .replace() to update those. This matches each character followed by a space or at the beginning of the string and uppercases those:

    function titleCase(str) {
      return str.toLowerCase().replace(/(^|s)w/g, m => m.toUpperCase());
    }
    
    console.log(titleCase("I'm a little tea pot"));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search