Codewar challenge

I have to keep the first word within the output capitalized only if the original word was capitalized, but my code is trasnforming every first word capitalized. What am doing wrong? expected output in the image
function toCamelCase(str){
let splittingWord = str.split(/-|_/);

let camelCaseString = "";

for(let i = 0; i < splittingWord.length; i++){
const upperLetters = splittingWord[i].toUpperCase()[0];
const lowerLetters = splittingWord[i].slice(1).toLowerCase();

if (i === 0) {
camelCaseString += upperLetters + lowerLetters;
} else {
camelCaseString += splittingWord[i].toUpperCase()[0]+lowerLetters;
}

}
console.log(camelCaseString);

}
toCamelCase("the-stealth-warrior");
function toCamelCase(str){
let splittingWord = str.split(/-|_/);

let camelCaseString = "";

for(let i = 0; i < splittingWord.length; i++){
const upperLetters = splittingWord[i].toUpperCase()[0];
const lowerLetters = splittingWord[i].slice(1).toLowerCase();

if (i === 0) {
camelCaseString += upperLetters + lowerLetters;
} else {
camelCaseString += splittingWord[i].toUpperCase()[0]+lowerLetters;
}

}
console.log(camelCaseString);

}
toCamelCase("the-stealth-warrior");
38 Replies
Joao
Joao12mo ago
Well, one way to approach this is: check if the first letter is lower case, in which case you don't need to do anything, or uppercase, in which case you also don't need to do anything. In other words, skip the first iteration and you should be done.
Sste
Sste12mo ago
Can you explain in more detail? I didn't understand
Joao
Joao12mo ago
What I mean is that the first letter should be left untouched, right? So in the first iteration of the loop you don't actually need to do anything there. You'd still need to change the returned value a bit to use that first fragment, plus the modified ones. I don't think you can combine spoiler tags with code on Discord.
Sste
Sste12mo ago
It still confuses for me what you are trying to say
Joao
Joao12mo ago
Ok, so you are splitting str into several fragments or splittingWords whatever you want to call it. What I'm saying is that you already know that the first segment does not need to be changed. Therefore the loop where you turn the first letter on each fragment to uppercase, doesn't need to start at 0. Because you know that the first fragment should not be modified at all. The exercise says that if it's lowercase leave it as is, but you should also leave it as is if it's already uppercase.
Sste
Sste12mo ago
It makes sense
Joao
Joao12mo ago
In your screenshot, the-stealth-warrior the firs segment is the and that word doesn't get modified. The same is true for the others.
Sste
Sste12mo ago
It's better if I just delete the upperLetters variable
Joao
Joao12mo ago
So, 1) split the words 2) iterate over the resulting array starting on the second index 3) return the first segment combined with the modifications you made during the loop Well I don't know if you need that variable or not to be honest, but that's the steps I would take to make this work.
Sste
Sste12mo ago
Thanks, I will try it
Joao
Joao12mo ago
A bit heavy on the use of array methods for my taste, I think there must be a way to simplify that.
vince
vince12mo ago
Definitely could be haha. I work a decent bit with React so I feel like most of the stuff you use in there are array methods
Joao
Joao12mo ago
Yeah definitely. I had to give it a try so here's my version: https://codepen.io/D10f/pen/qBQamaG
vince
vince12mo ago
Ohhh definitely much cleaner! I like it 🙂
Joao
Joao12mo ago
I like to come back to the basics for simple things 🙂
Gashy
Gashy12mo ago
This is my take on one, you can take it out of the template string if you want it a bit more readable https://codepen.io/gashydev/pen/mdQrmrV
Joao
Joao12mo ago
@sstephanyyy If you have it, share it!
Sste
Sste12mo ago
function toCamelCase(str) {
let camelCaseString = "";

if (str) {
let splittingWord = str.split(/[-_]/);

for (let i = 0; i < splittingWord.length; i++) {
const word = splittingWord[i];
const capitalizedWord = (i === 0) ? word : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
camelCaseString += capitalizedWord;
}
} else {
return camelCaseString;
}
}
function toCamelCase(str) {
let camelCaseString = "";

if (str) {
let splittingWord = str.split(/[-_]/);

for (let i = 0; i < splittingWord.length; i++) {
const word = splittingWord[i];
const capitalizedWord = (i === 0) ? word : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
camelCaseString += capitalizedWord;
}
} else {
return camelCaseString;
}
}
I still didn't complete the exercise
Sste
Sste12mo ago
it says this
Joao
Joao12mo ago
I think it's time for a break then. After so long, it's best to walk away for a while and let you brain work it out in the background.
Sste
Sste12mo ago
I did this. I have come back has a few minutes
Joao
Joao12mo ago
In the meantime I have a couple of suggestions to improve code quality overall. First, since you are checking for the existence of str you can make that return earlier:
function toCamelCase(str) {
if (!str) return '';

// rest of the code
}
function toCamelCase(str) {
if (!str) return '';

// rest of the code
}
This will avoid additional nesting. I highly suggest this video on the topic: https://www.youtube.com/watch?v=CFRhGnuXG-4
Sste
Sste12mo ago
humm, makes sense okay, I will watch it
Joao
Joao12mo ago
I think you have the right idea of what's going on, you're almost there. I'll give you a hint of how I did it: start the loop at 1 instead.
Sste
Sste12mo ago
I noticed it haha let me try
Joao
Joao12mo ago
If you start the loop at one you are essentially skipping the first fragment of the original string. So you can safely update the rest as you need without worrying whether it's the first iteration or not.
Sste
Sste12mo ago
like this? I am feeling so stupid because I can't solve an easy problem haha
function toCamelCase(str) {
let camelCaseString = "";

if (!str) {
const words = str.split(/[-_]/);
let res = "";

for (let i = 1; i < words.length; i++) {
const firstLetter = words[i][0].toUpperCase();
const rest = words[i].slice(1).toLowerCase();
res += firstLetter + rest;
}

}
}
function toCamelCase(str) {
let camelCaseString = "";

if (!str) {
const words = str.split(/[-_]/);
let res = "";

for (let i = 1; i < words.length; i++) {
const firstLetter = words[i][0].toUpperCase();
const rest = words[i].slice(1).toLowerCase();
res += firstLetter + rest;
}

}
}
Joao
Joao12mo ago
That looks right. Don't feel that way, we all have our own frame of reference. "Easy" it's very relative. Don't worry about checking for the existence of str yet. You can add that later. Just focus on the main task for now
Sste
Sste12mo ago
yessssssssssss, I did it!
function toCamelCase(str) {
let camelCaseString = "";

if (str) {
const words = str.split(/[-_]/);
let res = "";

for (let i = 1; i < words.length; i++) {
const firstLetter = words[i][0].toUpperCase();
const rest = words[i].slice(1).toLowerCase();
res += firstLetter + rest;
}

camelCaseString = words[0] + res;
}

return camelCaseString;
}
function toCamelCase(str) {
let camelCaseString = "";

if (str) {
const words = str.split(/[-_]/);
let res = "";

for (let i = 1; i < words.length; i++) {
const firstLetter = words[i][0].toUpperCase();
const rest = words[i].slice(1).toLowerCase();
res += firstLetter + rest;
}

camelCaseString = words[0] + res;
}

return camelCaseString;
}
Sste
Sste12mo ago
Sste
Sste12mo ago
thanks for all the help João
Joao
Joao12mo ago
No worries, congrats! You can check now the other answers and compare it. There's always many different ways to do things to you can see how other people approach the same problem. Well I guess in codewars you can do that as well, but I found that over there a lot of people tend to go for the absolute most concise answer... which is not always realistic or practical.
Sste
Sste12mo ago
yes. I will have to remake this problem all by myself to try to understand everything better hey, one more question...do u think solve this problems are useful or is it better to build real projects?
Joao
Joao12mo ago
I guess it depends on the person. I did for a while but I found more useful to build real projects. A lot of these exercises come up naturally anyway. But on the other hand from time to time it also useful to flex your mind with things you are not used to work with. Something that I find useful when coming to Discord and try to help out is that I need to solve issues that I didn't run into on my own, so that helps.
Gashy
Gashy12mo ago
Yeah I was about to say even though I've worked with web dev for a few years commercially I might delve into some of these code war things a bit deeper myself. There is a lot of stuff in JS that you dont actually use (or rarely when you do), so niche things like this can sometimes help in the long run, even if its introducing you to something new. It's also a good way to find/test out multiple solutions for the end product, exactly like how Vince, Joao and myself showed above, we all came to a similar end point but our solutions vary in different methods.
vince
vince12mo ago
Clean! I like this one
Joao
Joao12mo ago
I like to try different languages to expand myself a bit. I made this version in C just for fun as I've been practicing it for a while:
char* toCamelCase(const char* str)
{
static char res[100];

int i = 1;
int j = 1;

while (str[i] != '\0')
{
if (str[i] == '_' || str[i] == '-' || str[i] == ' ')
res[j] = toupper(str[++i]);
else
res[j] = tolower(str[i]);

i++;
j++;

};

res[0] = str[0];
res[j] = '\0';

return res;
}
char* toCamelCase(const char* str)
{
static char res[100];

int i = 1;
int j = 1;

while (str[i] != '\0')
{
if (str[i] == '_' || str[i] == '-' || str[i] == ' ')
res[j] = toupper(str[++i]);
else
res[j] = tolower(str[i]);

i++;
j++;

};

res[0] = str[0];
res[j] = '\0';

return res;
}