Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create copy of multi-dimensional array, not reference - JavaScript [duplicate]

This is also referred to as "deep copying", which I've found some articles on. Closest seems to be this one but it's for jQuery - I'm trying to do this without a library.

I've also seen, in two places, that it's possible to do something like:

arr2 = JSON.decode(JSON.encode(arr1)); 

But that's apparently inefficient. It's also possible to loop and copy each value individually, and recurs through all the arrays. That seems tiring and inefficient as well.

So what's the most efficient, non-library way to copy a JavaScript multi-dimensional array [[a],[b],[c]]? I am completely happy with a "non-IE" method if necessary.

Thanks!

like image 624
Randy Hall Avatar asked Dec 07 '12 03:12

Randy Hall


People also ask

How do you copy an array without references?

Use JSON. parse() and JSON. stringify() methods to copy array without reference in JavaScript. If these objects are simple objects, and they can be serialized in JSON.

How do I copy an array in JavaScript?

Because arrays in JS are reference values, so when you try to copy it using the = it will only copy the reference to the original array and not the value of the array. To create a real copy of an array, you need to copy over the value of the array under a new value variable.


2 Answers

Since it sounds like you're dealing with an Array of Arrays to some unknown level of depth, but you only need to deal with them at one level deep at any given time, then it's going to be simple and fast to use .slice().

var newArray = [];  for (var i = 0; i < currentArray.length; i++)     newArray[i] = currentArray[i].slice(); 

Or using .map() instead of the for loop:

var newArray = currentArray.map(function(arr) {     return arr.slice(); }); 

So this iterates the current Array, and builds a new Array of shallow copies of the nested Arrays. Then when you go to the next level of depth, you'd do the same thing.

Of course if there's a mixture of Arrays and other data, you'll want to test what it is before you slice.

like image 109
I Hate Lazy Avatar answered Sep 18 '22 15:09

I Hate Lazy


I'm not sure how much better JSON.stringify and JSON.parse than encode and decode, but you could try:

JSON.parse(JSON.stringify(array)); 

Something else I found (although I'd modify it a little):

http://www.xenoveritas.org/blog/xeno/the-correct-way-to-clone-javascript-arrays

function deepCopy(obj) {   if (typeof obj == 'object') {     if (isArray(obj)) {       var l = obj.length;       var r = new Array(l);       for (var i = 0; i < l; i++) {         r[i] = deepCopy(obj[i]);       }       return r;     } else {       var r = {};       r.prototype = obj.prototype;       for (var k in obj) {         r[k] = deepCopy(obj[k]);       }       return r;     }   }   return obj; } 
like image 33
Ian Avatar answered Sep 21 '22 15:09

Ian