Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why modifying array.slice() also changes the original array?

I am trying to modify a copied array without changing the original one. This is what I've tried, by using slice() method, but it doesn't work as expected:

//toFill holds the values I want to add into an array named secondArr, 
//replace every empty sting within secondArr with 0
var toFill = [0, 0, 0, 0];
var mainArr = [
  [" ", 1, 1, 1],
  [" ", 1, 1, 1],
  [" ", 1, 1, 1],
  [" ", 1, 1, 1]
];
var secondArr = mainArr.slice(0,4);
//this function returns a 1D array, stores the indices of all empty strings within an array
function findBlankSpaces(secondArr) {
  var emptyIndices = [];
  var innerArrLen = secondArr.length;
  var outterArrLen = secondArr[0].length;
  for (var i = 0; i < innerArrLen; i++) {
    for (var j = 0; j < outterArrLen; j++) {
      if (secondArr[i][j] == " ") {
        emptyIndices.push([i, j]);
      }
    }
  }
  return emptyIndices;
}

//this function returns the modified array, with empty spaces replaced with 0s
function fillWithZero(secondArr, toFill) {
  var emptyIndices = findBlankSpaces(secondArr);
  for (var i = 0; i < emptyIndices.length; i++) {
    secondArr[emptyIndices[i][0]][emptyIndices[i][1]] = toFill[i];
  }
}
//consoles
console.log(fillWithZero(secondArr, toFill));
console.log(mainArr);
//expected output in console is [[" ", 1,1,1], [" ",1,1,1], [" ",1,1,1], [" ",1,1,1]];
//actual output is [[0,1,1,1], [0,1,1,1], [0,1,1,1], [0,1,1,1]];
//I didn't modify mainArr, but only modified secondArr, why that mainArr also affected?

I didn't modify the mainArr, only created a copy by using slice(), but why it keeps changing when its copy changes?

This question is: Any way to stop this from happening or how do I call the mainArr again without any 0s in it, I want mainArr stays unchanged. Thanks

like image 815
WWL Avatar asked Mar 06 '19 03:03

WWL


1 Answers

As shown at Slice MDN, the slice method returns a shallow copy of the array that calls it. Deep copy discusses a few ways to deep copy objects in JS. A good one it mentions is

var secondArr = JSON.parse(JSON.stringify(mainArr))

This converts your array to JSON and then parses it into a new object

like image 174
Joseph Potter Avatar answered Nov 15 '22 00:11

Joseph Potter