0

working with this function call:

var StringData = window.ToCamelCase({ 'string': 'HELLO WORLD', 'remSpace': false });
console.log(StringData);

and this is my script function:

function ToCamelCase(data) {
    data['string'] = data['string'].replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
        return index == 0 ? word.toUpperCase() : word.toLowerCase();
    });
    if (data['remSpace']) {
        data['string'] = data['string'].replace(/\s/g, '');
    }
    return data['string'];
}

i dont get error; but not work properly, if i passed and string like this:

"HELLO WORLD"

this moment second word not put first letter uppercase

the output is: "Hello world" and i expect: "Hello World"

First letter per word Upper Case and the following Lower Case is the rule.

what am I doing wrong?

Jay Buckman
  • 581
  • 5
  • 18
  • 1
    Strings are immutable. `replace()` does **not* * modify the string on which it's used. It *returns* the modified string, which you aren't capturing. Consider `data['string'] = data['string'].replace(...)`. – Tyler Roper Jun 25 '19 at 16:45
  • I HAVE MODIFIED THE QUESTION. –  Jun 25 '19 at 16:49
  • at this moment second word not put first letter uppercase –  Jun 25 '19 at 16:50
  • @Teemu is true at this no need remove space... –  Jun 25 '19 at 16:53
  • 1
    @TylerRoper i have update the function and the question... –  Jun 25 '19 at 16:53

4 Answers4

3

You don't really need to use regex for this. You can split the string by using string.split(), then uppercase each element in the split array. Finally, recombine the array with spaces separating the elements if you want:

function ToCamelCase(data) {
    const words = data['string'].toLowerCase().split(' ');
    const uppercasedWords = words.map(word => {
        let splitWord = word.split('');
        splitWord[0] = splitWord[0].toUpperCase();
        return splitWord.join('');
    });
    return uppercasedWords.join(data['remSpace'] ? '' : ' ')
}

or more functionally,

function uppercaseFirstElement(textArray) {
    return [textArray[0].toUpperCase(), ...textArray.slice(1)];
}

function capitalizeWord(word) {
    return uppercaseFirstElement(word.split('')).join('');
}

function toCamelCase(sentence, removeSpace) { // Really it should be `toPascalCase`
    return sentence.toLowerCase().split(' ')
        .map(capitalizeWord).join(removeSpace ? '' : ' ');
}
Ian
  • 5,704
  • 6
  • 40
  • 72
  • Why do you use let instead of var? –  Jun 25 '19 at 17:05
  • A quick note, if you made the entire string lowercase *before* you `split` it, you wouldn't have to call `toLowerCase()` for every iteration :) Something [like this](https://jsfiddle.net/h784o9cb/). – Tyler Roper Jun 25 '19 at 17:12
  • @walternuñez Modern JavaScript (since version es6, which is supported in all recent browsers) adds the keywords `let` and `const` (constant version of `let`) to the language. These keywords are safer to use because they create block-scoped variables instead of function-scoped, they don't hoist variables, and they don't allow redeclaration of the same variable. Those are somewhat advanced topics so I'd recommend doing some research on it, but in short, `let` and `const` are safer and more predictable. – Ian Jun 25 '19 at 17:23
1

As mentioned by Ian, you do not need regular expressions for this job and it is probably more efficient to not use them.

That being said, if you DO want to make it work with a RegExp for whatever reason, you can use:

function toPascalCase(str) {
    return str.replace(/(?:^|\s*)(\S+)(?:\s*|$)/g, (match, word) => word[0].toUpperCase() + word.slice(1).toLowerCase());
}

This code uses an es6 arrow function so you will need to change it if you want to be compatible with old browsers. This is also based on the spec I could get from your question but there are a lot of case non-handled regarding special characters outside of letters / numbers / whitespace range (they will be considered part of the words - it might be what you want though).

One last note: What you are trying to achieve is actually called PascalCase. In camelCase, the very first letter is lowercase.

Bali Balo
  • 3,338
  • 1
  • 18
  • 35
0

First of all Ian's solution should be the correct one, since it is the simplest and understandable solution of them all.

If you are asking what's wrong with your code then my answer is this statement:

index == 0 ? word.toUpperCase() : word.toLowerCase()

is this statement what's causing all the problem. Your index is not 0 when it reaches to "W" of "World" so its going to make it lowercase.

Instead what you should be doing is capturing words and replace only the first letter of each word with an uppercase. Split method is a good solution, that's what Ian did. I have done something like this using the regex and replace, although its not necessary to do it like this.

function ToCamelCase(data) {
    data['string'] = data['string'].replace(/(?:\s|^)(\w+)(?=\s|$)/g, function(word, index) {
        var lowerWord = word.toLowerCase().trim();
        return lowerWord.substring(0, 1).toUpperCase() + lowerWord.substring(1, word.length) + " "
    });
    if (data['remSpace']) {
        data['string'] = data['string'].replace(/\s/g, '');
    }
    return data['string'];
}
Shababb Karim
  • 3,614
  • 1
  • 22
  • 35
0

In your code index will return always 0 as it is not iterating all your string characters here I have tried with my code just replace with your code and let me know the result.

var StringData = window.toCamelCase({ 'string': 'HELLO WORLD', 'remSpace': false });
console.log(StringData);

function toCamelCase(data) {
 var str = data['string'];
 var isRemoveSpc = data['remSpace'];
 var len = data['string'].length;
 var newStr = "";
 for(var i = 0; i < len; i++){
  if( i == 0) {
   newStr += str.charAt(i).toUpperCase();
  } else if(str.charAt(i) == " ") {
   if(isRemoveSpc) {
    i++;
    newStr += str.charAt(i).toUpperCase();
   } else {
    newStr += str.charAt(i);
    i++;
    newStr += str.charAt(i).toUpperCase();
  }  
 } else {
   newStr += str.charAt(i).toLowerCase();
 }
}
  return newStr;
}


Srujal Patel
  • 145
  • 8