4

I want to make a clone of multidimensional Array so that i can play arround with the clone array without affecting main Array.

I'm using following function to do so:

Array.prototype.clone = function () { 
   var newArray = new Array(this.length);
     for(var i=0; i < this.length; i++ ){
        newArray[i] = this[i];
   }
   return newArray;
};

But problem which is since it is using array prototype so it will clone my all array.so can any body tell me what is the best way of doing this.

3 Answers 3

10

vsync is correct, my first answer doesn't handle var a = [[1,2],[3,4]];
So here's an improved version

var a = [[1,2],[3,4]];
Array.prototype.clone = function() {
    var arr = this.slice(0);
    for( var i = 0; i < this.length; i++ ) {
        if( this[i].clone ) {
            //recursion
            arr[i] = this[i].clone();
        }
    }
    return arr;
}

var b = a.clone()

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

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

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

//[[1, 2], [3, 4]]
//[[1, 2], [3, 4]]
//[[1, 2], [3, 4]]
//[[1, 2], ["a", 4]]
Sign up to request clarification or add additional context in comments.

2 Comments

The first answer didn't work properly for me but this one worked perfectly. Thanks!
Thank you so much for posting this method here. I got another improvement for it: if( this[i] && this[i].clone ) { to support sparse arrays (or whatever you call it when some values are null)
5

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

2 Comments

You could check for the presence of a clone method on each object in the array, and call it to clone the object if present. This will handle the recursion of arrays and also allow any other objects with clone methods to be deep-copied as well.
it doesn't clone stuff like this properly: var a = [[1,2],[3,4]];
4

I found that this approach is better than meouw's :

var source = [
  [1, 2, {c:1}],
  [3, 4, [5, 'a']]
];

// Create a new method ontop of the "Array" primitive prototype:
Array.prototype.clone = function() {
  function isArr(elm) {
    return String(elm.constructor).match(/array/i) ? true : false;
  }

  function cloner(arr) {
    var arr2 = arr.slice(0),
        len = arr2.length;

    for (var i = 0; i < len; i++)
      if (isArr(arr2[i]))
        arr2[i] = cloner(arr2[i]);

    return arr2;
  }
  return cloner(this);
}

// Clone
var copy = source.clone();

// modify copy
copy[0][0] = 999;

console.dir(source);
console.dir('**************');
console.dir(copy);

Another method, which can only work on data sets which have primitives
as values (String, Numbers, Objects) :

var source = [
  [1,2, {a:1}],
  ["a", "b", ["c", 1]]
];

// clone "srouce" Array
var copy = JSON.parse(JSON.stringify(source));

// modyfy clone
copy[0][0] = 999;

// print both arrays
console.dir(copy)
console.log('***********')
console.dir(source)

1 Comment

I have posted an improved answer :)

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.