3

The problem statement is, i should replace the any digit below 5 with 0 and any digit 5 and above with 1.

I am trying to reassign values, but it is not affecting, Why?

function fakeBinary(n) {
    let numbersArr = n.split('');
    numbersArr.forEach(num => {
        if(Number(num) < 5) {
            num = '0';
        } else if(Number(num) >= 5) {
            num = '1';
        }
    });
    return numbersArr.join('');
}

console.log(fakeBinary('3457'));

I except the output of 0011, but the actual output is 3457.

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
iamPavan
  • 255
  • 4
  • 15

4 Answers4

6

forEach doesn't bring the element's reference for primitive values but rather brings a copy of the value in your case. You can easily access that manually through the index, though:

function fakeBinary(n) {
    let numbersArr = n.split('');
    numbersArr.forEach((num, i) => {
//                          ^--- note that `i` is brought and used below to access the element at index [i].
        if(Number(num) < 5) {
            numbersArr[i] = '0';
        } else if(Number(num) >= 5) {
            numbersArr[i] = '1';
        }
    });
    return numbersArr.join('');
}


console.log(fakeBinary('3457'));

Please note that you may also use other prototypes, I just tried to stay as close as possible to your solution, you may also want to use map or, even (not appropriate, though) reduce or even a regular for loop.

briosheje
  • 7,356
  • 2
  • 32
  • 54
  • Ahhhhg this is so weird lol, if you're iterating JSON objs instead of num with forEach. You can update properties on ea elem and the changes will be reflected in the root array afterwards, however you can't re-assign the entire obj. Probably more accurate to say it brings a **shallow clone** no? If it was a true copy you wouldn't be able to have property changes affect the original array? – Llama D'Attore Apr 17 '23 at 13:57
5

forEach used like that won't do anything - use map instead.

let numbersArr = n.split("").map(num => {
  if (Number(num) > 5) {
    num = "0";
  } else if (Number(num) <= 5) {
    num = "1";
  }
  return num;
});

return numbersArr.join("");

Note that to produce your desired output, you need to change your conditions slightly:

if (Number(num) >= 5) {
  num = "1";
} else {
  num = "0";
}
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
1

To do it with forEach, you would need to use the additional arguments to reference the array and the index.

function fakeBinary(n) {
    let numbersArr = n.split('');
    numbersArr.forEach((num, index, arr) => {
        if(Number(num) < 5) {
            arr[index] = '0';
        } else if(Number(num) >= 5) {
            arr[index] = '1';
        }
    });
    return numbersArr.join('');
}

console.log(fakeBinary('3457'));

But forEach is not the correct way to return a new array. You want to use map()

function fakeBinary(n) {
    return n
      .split('')
      .map(num => (Number(num) < 5) ? '0' : '1')
      .join('');
}

console.log(fakeBinary('3457'));
epascarello
  • 204,599
  • 20
  • 195
  • 236
  • any reason to bring the third argument in the `forEach`? it shoulnd't be revelant, right? – briosheje Aug 06 '19 at 14:23
  • You can use the array directly, but if you were to do the split and forEach on one line it would not be possible to do it. – epascarello Aug 06 '19 at 14:26
  • Oh, didn't notice that, just copied the raw code from the OP and didn't notice that first. Indeed, that makes sense. – briosheje Aug 06 '19 at 14:27
0

A shorter version using Array.from()

const fakeBinary = (str) => Array.from(str, n => +(+n >= 5)).join('');

console.log(fakeBinary('3457'));
User863
  • 19,346
  • 2
  • 17
  • 41