Create Copy of Multi-Dimensional Array, Not Reference - JavaScript

Create copy of multi-dimensional array, not reference - JavaScript

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.

Why can't I make a copy of this 2d array in JS? How can I make a copy?

A hat-tip to @Redu's answer which is good for N-dimensional arrays, but in the case of 2D arrays specifically, is unnecessary. In order to deeply clone your particular 2D array, all you need to do is:

let oldLifeMap = lifeMap.map(inner => inner.slice())

This will create a copy of each inner array using .slice() with no arguments, and store it to a copy of the outer array made using .map().

Clone a 4D multidimensional array

You could use a simple recursive function that replaces arrays with copies after recursively handling its values:

function deepCopy(value) {
if (Array.isArray(value)) {
return value.map(deepCopy);
}
return value;
}

const data = [[[0]]];
const copy = deepCopy(data);
data[0][0][0] = 123;
console.log(data);
console.log(copy);

For a deep copy of a JavaScript multidimensional array, going one level deep seems sufficient. Is this reliably true?

Your test is flawed for whether a true copy is being made which makes your conclusion incorrect that you are getting a full copy of all the data in the nested arrays. You are only doing a two level copy, not an N level copy.

Javascript is a garbage collected language so you don't actually delete variables or objects and, even if you tried that doesn't affect the same variable if it's being referenced somewhere else in your code. To see if you truly have a completely independent copy, try nesting an object two levels deep and then change a property on the object in the original array. You will find that the same object changes in the cloned array because you aren't doing a deep clone. Both arrays have a reference to the exact same object.

Here's an example.

function cloneArray(arr) {  
// Deep copy arrays. Going one level deep seems to be enough.
var clone = [];
for (i=0; i<arr.length; i++) {
clone.push( arr[i].slice(0) )
}
return clone;
}

var x = [[{foo: 1}]];

var y = cloneArray(x);
x[0][0].foo = 2;

// now see what the value is in `y`
// if it's 2, then it's been changed and is not a true copy
// both arrays have a reference to the same object
console.log(y[0][0].foo); // logs 2

The same result would happen if the third level was another array too. You will have to recursively traverse every element that is an object type and then clone that object itself to get a complete clone of everything in the nested arrays.

If you want code that will do a deep copy (to an arbitrary level) and work for all data types, see here.

FYI, your cloneArray() function assumes that all first level members of your array are arrays themselves and thus doesn't work if it contains any other type of value.

Clone Multidimensional Array in javascript

You need to use recursion

var a = [1,2,[3,4,[5,6]]];

Array.prototype.clone = function() {
var arr = [];
for( var i = 0; i < this.length; i++ ) {
// if( this[i].constructor == this.constructor ) {
if( this[i].clone ) {
//recursion
arr[i] = this[i].clone();
break;
}
arr[i] = this[i];
}
return arr;
}

var b = a.clone()

console.log(a);
console.log(b);

b[2][0] = 'a';

console.log(a);
console.log(b);

/*
[1, 2, [3, 4, [5, 6]]]
[1, 2, [3, 4, [5, 6]]]
[1, 2, [3, 4, [5, 6]]]
[1, 2, ["a", 4, [5, 6]]]
*/

Any other objects in the original array will be copied by reference though

Why is a spread element unsuitable for copying multidimensional arrays?

Arrays are objects, and [...a] creates a shallow copy of a array object.

For the language itself there are no multidimentional arrays - there are another arrays inside an array. It doesn't matter if contains arrays, plain objects, functions or primitives. For primitives, their values will be copied. Otherwise, the references to objects will be copied. This is what

It's the same case with Object.assign() and Object spread operators

part refers to.

And regarding

The above code sample works just the same as if you'd copied the array in a to b using the .slice() method

...it truly does. This is a neater way to write a.slice() or [].concat(a). With a considerable exception. ES6 rest operator (as well as Array.from(a)) works equally for all iterables, not just for arrays.

For a deep copy of an object ES6 offers nothing new, an object (which an array is) should be recursively copied by hand. To address all the concerns it still makes sense to use proven third-party helper functions, such as Lodash cloneDeep.

Issue with multi-dimensional arrays in JavaScript

As your log indicates, data[1] is undefined.

There are a number of ways to define the values of data[0–99] as empty arrays. In es6 for instance, Array(100).fill([]). See https://stackoverflow.com/a/41246860/1664393.

How can I create a two dimensional array in JavaScript?

Practically? Yes. You can create an array of arrays which functions as an 2D array as every item is an array itself:

let items = [
[1, 2],
[3, 4],
[5, 6]
];
console.log(items[0][0]); // 1
console.log(items[0][1]); // 2
console.log(items[1][0]); // 3
console.log(items[1][1]); // 4
console.log(items);


Related Topics



Leave a reply



Submit