1

I am basically looking for a general function copy(array) that will return identical n-dimensional array without any references to the former one.

11
  • none... but don't judge me, i am beginner in javascript. i've only looked at this: stackoverflow.com/questions/419858/…, and it wasn't general enough for my case. Commented Jun 8, 2012 at 0:35
  • 1
    @Ognjen - Java is not JavaScript. Commented Jun 8, 2012 at 0:36
  • btw i am porting some code from java to js, if you wonder why i needed this :) Commented Jun 8, 2012 at 0:36
  • Do you have to have an arbitrary copy of any types? If you know the types and dimensions of the array, the problem is a lot easier. Commented Jun 8, 2012 at 0:37
  • 1
    @Derek - A shallow copy makes a copy of the top level items, but if there are any items deeper than that (e.g. arrays in arrays or arrays in a property), it does not make a copy of those (they end up being references to the same objects). A deep copy makes sure that every item at every level is a copy. A deep copy usually uses recursion. Commented Jun 8, 2012 at 0:44

4 Answers 4

5

This works for arrays, it won't work for nested objects (that aren't Arrays):

function copy(arr){
    var new_arr = arr.slice(0);
    for(var i = new_arr.length; i--;)
        if(new_arr[i] instanceof Array)
            new_arr[i] = copy(new_arr[i]);
    return new_arr;
}

Use it like this:

var arr = [
   [[1,2,3],[75]], 100,
   [[[1]]], [],
   [1,[2,[3],4],5], 6, 7, 8
];

var new_arr = copy(arr);
Sign up to request clarification or add additional context in comments.

Comments

1

Using jQuery (works for arrays and "plain" objects):

var a = [[1,[2,3]],[4]];
var b = $.extend(true, [], a);
a[0][0] = 42;             // modify object in a
alert(JSON.stringify(b)); // [[1,[2,3]],[4]]

Or JSON direct (if all objects are JSON-izable):

var a = [[1,[2,3]],[4]];
var b = JSON.parse(JSON.stringify(a))
a[0][0] = 42;             // modify object in a
alert(JSON.stringify(b)); // [[1,[2,3]],[4]]

Older versions of IE (8? 7?) will need a shim for the JSON object.

1 Comment

Small note: If the value is undefined, it would not be transformed into JSON.
0

I just wanted to add to Paulpro's answer. Note that this is identical to his answer except that I changed copy(new_arr[i]) to copy(arr[i]), and new_arr.length to arr.length.

function copy(arr){
var new_arr = arr.slice(0);
for(var i = arr.length; i--;)
    if(new_arr[i] instanceof Array)
        new_arr[i] = copy(arr[i]);
return new_arr;
}

The reason copy(new_arr[i]) worked is because the .slice copied over what arr[i] was pointing at, making them equal.

Also, while Paulpro's answer works for all cases, if by chance each member of each dimension of the multi-dimensional array is either an array or a non-array you can make it more efficient by only slicing non-array dimensions. I mean what is the point of copying over an array of pointers that will simply be overwritten by the following recursion?

function copy(arr){
if(arr[0] instanceof Array){
    var new_arr = new Array(arr.length);
    for(var i = arr.length; i--;)
        new_arr[i] = copy(arr[i]);
}
else{var new_arr = arr.slice(0);}
return new_arr;
}

Comments

0

This is my solution to clone a multidimensional array; Actually i had to invent Array.prototype.clone() in order to invent a function to generate N dimension array and initialize it with a value.

Array.prototype.clone = function(){
  return this.reduce((p,c,i) => (p[i] = Array.isArray(c) ? c.clone() : c, p),[])
}

function arrayND(...n){
  return n.reduceRight((p,c) => c = (new Array(c)).fill(true).map(e => Array.isArray(p) ? p.clone() : p ));
}

var arr = arrayND(...[4,4,4],8); //last argument is the initializing value
arr[0][1][3] = "eight";
console.log(JSON.stringify(arr));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.