Please scrutinize my approach to a problem

Hey guys, first forum post! Happy to be here :slight_smile:

I’d love some feedback on how I solved this exercise:

Here is my code:

function titleCase(str) {
  let newStr = `${str[0].toUpperCase()}`;
  for (let i = 1; i < str.length; i++)
    if (str[i - 1] == " ") {
      newStr += str[i].toUpperCase();
    } else { newStr += str[i].toLowerCase() }; 
  }
  return newStr;
}

titleCase("I'm a little teapot");  // returns "I'm A Little Teapot"

So basically, I always check the hints after passing an exercise to see if there are more clever ways to approach them. Well I noticed that the first two given solutions convert a string into an array using .split(). See below.

Solution 1

String.prototype.replaceAt = function(index, character) {
  return (
    this.substr(0, index) + character + this.substr(index + character.length)
  );
};

function titleCase(str) {
  var newTitle = str.split(" ");
  var updatedTitle = [];
  for (var st in newTitle) {
    updatedTitle[st] = newTitle[st]
      .toLowerCase()
      .replaceAt(0, newTitle[st].charAt(0).toUpperCase());
  }
  return updatedTitle.join(" ");
}

Solution 2

function titleCase(str) {
  var convertToArray = str.toLowerCase().split(" ");
  var result = convertToArray.map(function(val) {
    return val.replace(val.charAt(0), val.charAt(0).toUpperCase());
  });
  return result.join(" ");
}

Solution 3

function titleCase(str) {
  return str.toLowerCase().replace(/(^|\s)\S/g, L => L.toUpperCase());
}

My question is, since splitting the string into an array isn’t necessary in this exercise, is it somehow preferable or more beneficial than the way I did it? Or is my solution actually better? I am still new to coding, so I haven’t yet gotten a grasp on regex (which clearly seems to be the ideal solution, here).

Any feedback would be greatly appreciated!

Your code has been blurred out to avoid spoiling a full working solution for other campers who may not yet want to see a complete solution. In the future, if you post a full passing solution to a challenge and have questions about it, please surround it with [spoiler] and [/spoiler] tags on the line above and below your solution code.

Thank you.

I don’t know how much difference there would be performance wise

But at this point I suggest you focus more on making your code readable (ample use of comments is always a good idea, plus good names for variables)

I don’t really quite like any of the four solutions you proposed, because they are not as readable as they could be

But you solved it, good work!

  ...
  let newStr = `${str[0].toUpperCase()}`;
  ...

You don’t need to use a template string - the first character is already a string, you don’t need to convert it to a string.

  ...
      newStr += str[i].toLowerCase()
  ...

Converting any other characters to lowercase when title casing breaks things like acronyms. So just concatenate str[i] here instead.

Not necessarily. The way you’ve done it is almost the most efficient way. This is given certain conditions (which are present for the tests): that the string only uses ASCII characters and that there is only ever one space between words.