1

OK. Let me try to say this in some sort of comprehensible manner. I'm an amateur programmer writing my own take on a neural network in javascript. (Without having seen the code for a neural network before)

I was having problems with an array changing when I was trying to change a copy of the array. (Not the original)

I soon realized after rereading what I'd written that when you assign an identifier to an array it doesn't make the identifier a new object with a copy of the array. Instead, it makes a reference to the original array object, for example:

var arr = [1,2,3];
var arr2 = arr;
arr2[0] = 9;

alert(arr);
//Alerts "9,2,3"  

With this mind, I googled and found a quick solution:

var arr = [1,2,3];
var arr2 = arr.slice();
arr2[0] = 9;

alert(arr);
//Alerts "1,2,3"

So I changed this in my actual project expecting to see my work completed, but no! I was getting the exact results as before where my array was changing even though it was not supposed to.

After much effort at debugging, I finally worked out that the problem here is that I have a large array of subarrays, which in turn have subarrays. In code this looks like:

var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];

As you can see, there is one big array that contains 3 smaller arrays, each of which contains two even smaller arrays, each of which contains a number. In my project, it's more complicated than this and has a couple more layers but this is a decent representation.

So what did I expect to happen?

var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
var other = arr.slice();
other[0][0][0] = "Uh Oh";

alert(arr);
//Outputs "1,2,3,4,5,6,7,8"

What actually happened?

alert(arr);
//Outputs "Uh Oh,2,3,4,5,6,7,8"

Why does this happen? How can I fix it? Thanks in advance.

Aden Power
  • 13
  • 2

1 Answers1

0

Try following

var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
var other = JSON.parse(JSON.stringify(arr));
other[0][0][0] = "Uh Oh";

console.log(arr);

Reasoning

arr.slice() creates different reference for the array, however, any child object/array will still continue to hold the same reference. But you need to change the references of the child object/array as well, for that convert it into a string and then back to object - It will create different references for all the objects.

Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
  • Wow thanks! But can you explain why the problem happens? Also why this fixes it but splice doesn't? – Aden Power Apr 06 '18 at 10:17
  • @AdenPower I've flagged a dupe that explains it. Basically, if you do `.slice` you get a *shallow* copy - in other words only the top level array is a new object, everything contained is still a reference to the old arrays. – VLAZ Apr 06 '18 at 10:19