0

Here's my function. It's supposed to return backgroundColor instead of backgroundcolor.

What's my problem?

function camelize(str) {
  let newStr = str.split('-');
  newStr.forEach((item, index) => {
    if (index > 0) {
      item.toLowerCase();
      item = item[0].toUpperCase() + item.slice(1);
    }
  });

  newStr = newStr.join('');
  return newStr;
}
console.log(camelize("background-color")); //'backgroundсolor' instead of 'backgroundColor'
Patfreeze
  • 680
  • 6
  • 16
Heaven
  • 41
  • 4
  • Well your code was full of weirdness. I had to add () => and remove some newlines and add a ); Secondly you never save or return any of the changes – mplungjan Oct 07 '21 at 19:59
  • Assigning to the local variable doesn't change the original array. – Barmar Oct 07 '21 at 19:59
  • 1
    strings are immutable, and forEach doesn't return; change one of those things. hint: assign `newStr[index]` instead of item. – dandavis Oct 07 '21 at 20:01
  • `const camelize = str => str.trim().toLowerCase().replace(/-/g, ' ').replace(/\s+([a-z])/g, $1 => $1.toUpperCase()).replace(/ /g, '')` trim it, lowercase it all, replace - with space, replace letters after space with cap version, remove spaces – Lawrence Cherone Oct 07 '21 at 20:10
  • @Barmar it looks like only objects or arrays can be assigned by the link. But it's not about their properties or elements. They are just copied. There's an [example](https://jsfiddle.net/pt27snw4/). Am I right? – Heaven Oct 07 '21 at 20:26
  • 1
    Correct. JavaScript doesn't have references to array elements and object properties. – Barmar Oct 07 '21 at 20:28
  • @Heaven Please return and interact with the people who spent time answering your question – mplungjan Oct 09 '21 at 18:59

2 Answers2

5
  1. You need a map
  2. you need to return the item

I simplified the code

const camelize = str => str
  .toLowerCase()
  .split('-').map((item, index) => index > 0 ? 
      item[0].toUpperCase() + item.slice(1) : item)
  .join('');

console.log(camelize("background-color")); 
console.log(camelize("Background-color")); 
console.log(camelize("BACKGROUND-COLOR")); 

Closer to your old code

function camelize(str) {
  const parts = str.toLowerCase().split('-');
  let newStr = parts.map((item, index) => {
    if (index > 0) {
      item = item[0].toUpperCase() + item.slice(1);
    }
    return item
  });

  newStr = newStr.join('');
  return newStr;
}
console.log(camelize("background-color"));
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 2
    One suggestion. Move the `item.toLowerCase()` outside the `if` statement so that the first word is always lowercased. Otherwise the function would break with this input `Background-color`. – War10ck Oct 07 '21 at 20:03
  • If I may make one more suggestion, remove the else and place the `item = item.toLowerCase();` at the top of the map iteration function. This should catch the final edge case of `Background-COLOR` which would still fail in this case. Sorry, not trying to nitpick just helping to form a fool-proof solution for any combination of casing. – War10ck Oct 07 '21 at 20:08
  • 1
    @War10ck Ok, done – mplungjan Oct 07 '21 at 20:08
  • 1
    Nice! Hadn't thought of including it before map. That's elegant. +1 – War10ck Oct 07 '21 at 20:09
  • 1
    @War10ck and cut it some more :) – mplungjan Oct 07 '21 at 20:18
  • 1
    That's rockstar status buddy! – War10ck Oct 07 '21 at 20:23
4

item is a local variable inside the function. Assigning to it has no effect on newStr.

item.toLowerCase() returns a new string, it doesn't modify the string in place (JS strings are immutable). You need to assign it back to the variable to change it.

Use map() instead of forEach() so you return a new array with the results.

function camelize(str) {
  let oldStr = str.split('-');
  let newStr = oldStr.map((item, index) => {
    if (index > 0) {
      item = item.toLowerCase();
      item = item[0].toUpperCase() + item.slice(1);
    }
    return item;
  });

  return newStr.join('');
}
console.log(camelize("background-color")); //'backgroundсolor' instead of 'backgroundColor'
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    One suggestion. Move the `item.toLowerCase()` outside the `if` statement so that the first word is always lowercased. Otherwise the function would break with this input `Background-color`. – War10ck Oct 07 '21 at 20:04