2

I have 2 arrays: A and B, when I change one both change. Is there a way to edit one without changing the other one.

a = [[0,0,0,0,0],[0,0,0,0,0]] 
b = [[1,2,3,4,5],[6,7,8,9,10]]
a = b.slice(0)
a[0][0] = 10
console.log(a) /* [[10,2,3,4,5],[6,7,8,9,10]] */ 
console.log(b) /* [[10,2,3,4,5],[6,7,8,9,10]] */ 

The a is fine but I need b to stay [[1,2,3,4,5],[6,7,8,9,10]]

Calvin Nunes
  • 6,376
  • 4
  • 20
  • 48
  • 1
    When you slice b and assign it to a, a now references b. You need to make sure they are not references of each other. – Sterling Archer Jun 12 '18 at 17:29
  • Possible duplicate of [Copying array by value in JavaScript](https://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript) – varun sharma Jun 13 '18 at 19:31
  • You can use `a = JSON.parse(JSON.stringify(b));` instead of `a = b.slice(0)` `slice()` , `contat()` works for shallow copying i.e. for single dimensional array. – varun sharma Jun 16 '18 at 04:46

4 Answers4

4

When you do splice, you change the reference of a and b, however, the reference of arrays in array b still share references, hence, update your code to following. Use Array.map

a = [[0,0,0,0,0],[0,0,0,0,0]] 
b = [[1,2,3,4,5],[6,7,8,9,10]]
a = b.map(x => [...x])
a[0][0] = 10
console.log(a) /* [[10,2,3,4,5],[6,7,8,9,10]] */ 
console.log(b) /* [[1,2,3,4,5],[6,7,8,9,10]] */
Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
2

You can use map to slice each array.

a = [[0,0,0,0,0],[0,0,0,0,0]] 
b = [[1,2,3,4,5],[6,7,8,9,10]]
a = b.map(o=>o.slice(0));
a[0][0] = 10
console.log(a);
console.log(b);

Doc: map()

Eddie
  • 26,593
  • 6
  • 36
  • 58
2

You take a shallow copy with Array#slice, which means nested arrays are taken by their object reference.

You could use Array#map with a check for arrays and map these recursively.

const deep = a => Array.isArray(a) ? a.map(deep) : a;

var a = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]],
    b = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]];

a = b.map(deep);
a[0][0] = 10;

console.log(a);
console.log(b);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

slice(), like Object.freeze() have a shallow scope, so this works:

var a = [1,2,3,4];
var b = a.slice(0);

a[0] = 10;
console.log(b); // [1, 2, 3]
console.log(a); // [10, 2, 3, 4]

But this doesn't work:

var a = [[0,0,0,0,0],[0,0,0,0,0]]; //multidimensional!
var b = [[1,2,3,4,5],[6,7,8,9,10]];

a = b.slice(0);
a[0][0] = 10;
console.log(a); 
console.log(b);

Then, the key is go deep with slice(), for or something, Here an example using for:

var a = []; 

for (var i = 0, len = b.length; i < len; i++) {
    a[i] = b[i].slice();
}

Keep in mind that const won't work:

var a = [[0,0,0,0,0],[0,0,0,0,0]]; 
const b = [[1,2,3,4,5],[6,7,8,9,10]];// doesn't work

var a = b.slice(0);

a[0][0] = 10; // a changes b
console.log(a); 
console.log(b); 
Emeeus
  • 5,072
  • 2
  • 25
  • 37