Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Matt Jones
Matt Jones
1,950 Points

Converting snake_case to camelCase.

I'm having a bit of trouble converting strings to camel case. I can change all but strings in snake case. How could I add that into this code?

function toCamelCase(str){  

return (str||'').toLowerCase().replace(/(\b|-)\w/g, function(m) {
return m.toUpperCase().replace(/-/,'');


  });
}

2 Answers

nico dev
nico dev
20,364 Points

Hi Matt Jones ,

Great challenge! And you're almost there. There's a couple of things that's not helping you though. One is the \b flag, since it is intended to receive a letter (not a special character) and will return that letter when appropriate (when non-letter characters around).

The other detail is, although the inner replace() was correct, you're specifying the hyphen character instead of the underscore there. Unless I may have misunderstood your intention, I guess you wanted to remove the underscore from the snake_case word, right?

Here is one of the possible ways you can do it, and this is the source where I found it:

function toCamelCase(str) {
    const result = str.toLowerCase().replace(/_([a-z])/,function(m){return m.toUpperCase();}).replace(/_/,'');
    return result;
};

Hope that was what you were looking for, and that it helps you move ahead.

Matt Jones
Matt Jones
1,950 Points

Thanks for the reply, great help! I should have been a little more specific though, I'm looking at turning all strings into camelCase and with my code I'm successful, until I reach snake_case. That's the only string that won't convert and I was just wondering how I could add that to my code :)

nico dev
nico dev
20,364 Points

Oh no, sorry for my misunderstanding. Hope I'm not taking more of your time to explain it to me than to actually solve it |o| but do you mind giving further explanation on exactly what you're referring to as string and what exact output you want? I'm not quite clear.

Also, I am almost sure camelCase never starts with caps, but the first caps is the initial of the second word; with your code above, though, seems like you will start the word with caps, right?

Still another detail is that the special character \w includes every alphanumeric character including the underscore.

So:

  • If what you want as an input is a whole sentence and making each word's initial capitalized, then you're doing fine.

  • If you want to add to that making "snake_case" become into "Snake_Case" (I guess it's not snake_Case because that's opposite of what you're doing with all the other words, yes?), then you can add my bit above (except the last replace, that will remove the underscore) after your toLowerCase() and before the other replace(), like so:

function toCamelCase(str){
    return str.toLowerCase()    // We convert everyone into lowercase.
    .replace(/_([a-z])/,function(m){return m.toUpperCase();})    // Only letter after underscore to uppercase.
    .replace(/(\b|-)\w/g, function(m) {return m.toUpperCase()    // Letter after space or hyphen to uppercase.
    .replace(/-/,'');    // Remove any hyphen.
  });
}
toCamelCase("This is a simple short camel_case sentence");

NOTE: Personally, I have a feeling it's better to store the values in a let/const (so you can use it later, would it be needed), and then return that let/const. (I guess this should be a let but I'm still getting the hang of ES6.) :)

  • If you want to also remove the underscore, then just add it to the last replace (that is, after any lower/uppercase has been set).

Honestly, I could think of a lot of scenarios but I do really feel like making shots in the dark if you don't provide more context of what you want to do specifically, like some examples of my questions are: your input to the function (the argument/s) is it a series of words separated by hyphen? By space? Or is not a series of words and you're trying different words alone? You want camel_case to be what: camel_Case? Camel_Case? camelCase? The rest of the words should be separated or together and camelCased? I guess camelcase is when there's no space in between them and every word but the first one, are capitalized, right?

Sorry, Matt, really want to help you and happily spent some hours on this(and I gladly would spend some more with a little more of context), but I feel like a little blind and hand-tied to actually help you.

Matt Jones
Matt Jones
1,950 Points

It's a case of turning "This is a string" to "thisIsAString" and "snake_case" to snakeCase.

Matt Jones
Matt Jones
1,950 Points

Thank you so much for taking the time to explain though, it's been invaluable and really appreciated :)

nico dev
nico dev
20,364 Points

Hey again Matt!

Trust me it is really exciting helping you with this challenge, and it does teach me a lot too haha so it's mutual benefit, right? :)

Sorry, though, for taking so long in my answers; I suspect it's possible that we have a timezone difference that doesn't help a lot in speediness.

Well, that's a tricky one, I think, because you want both that every word except the first one may start with uppercase but then also that when it has a hyphen, don't; instead camelcase that word. I think that's our biggest challenge. I found a way around it with a conditional. Although I don't know if it's the most simply beautiful and elegant solution ever, but at least gets the job done while you find it :)

This is it, please check it by yourself and tell me if it works on your particular project. Otherwise, if you're really patient to wait for my replies, I'm more than happy to try any other thing if this doesn't work for some reason. Now take a look at a couple of notes I will add below the code of things you may like to take into account (or at least I could think of so far).

function toCamelCase(str) {
    if (/_/.test(str)) {
    let finalStr = 
        str.replace(/_[a-z]/,function(p1){
          return p1.toUpperCase();
        })
    .replace(/_/,'');
    return finalStr; 
  } else {
    let result =
        str.toLowerCase()
        .replace(/\s\S/g, function(p1) {
          return p1.toUpperCase();
        })
        .replace(/\s/g,'');
    return result;
  }  
}

console.log(toCamelCase("camel_case"));
console.log(toCamelCase("This is a string"));

I tried this one in CodePen and it worked perfectly for the examples you gave me and what you told me you wanted to achieve. Now some things you might like to take into account:

  1. This is a conditional, it means if the word has a hyphen it won't capitalize the first word like in others. For that reason, if instead of camel_case alone (like for instance the name of a class in your HTML/CSS), you'd have it in between a sentence, this presents a double challenge: you'd have an uncapitalized (or camelcased) word together with the other words, and it might be difficult to distinguish that's another word. Example: if you have "This is a short camel_case string", instead of "This is a string" like you said, the return/output would be "thisIsAShortcamelCaseString". Notice the problem between 'short' and 'camel'? Not sure if you were looking for that scenario, though. because like I told you, it contradicts its very essence of capitalizing every word. I let you think about it and tell me your thoughts.

  2. Do take into account possible scenarios like if people add a comma, or other symbols, but I'm sure this is only the skeleton of the whole thing, and you must build upon it, either programming "defensively" or indicating what to input and what not to the user via UI or alike and making some form of input control.

Looking forward to knowing if it worked or if you're looking for something different! Thanks for your patience in waiting and for allowing to help. :)