[ACCEPTED]-(Deep) copying an array using jQuery-jquery
Since Array.slice() does not do deep copying, it 7 is not suitable for multidimensional arrays:
var a =[[1], [2], [3]];
var b = a.slice();
b.shift().shift();
// a is now [[], [2], [3]]
Note 6 that although I've used shift().shift()
above, the point 5 is just that b[0][0]
contains a pointer to a[0][0]
rather than a value.
Likewise 4 delete(b[0][0])
also causes a[0][0]
to be deleted and b[0][0]=99
also changes 3 the value of a[0][0]
to 99.
jQuery's extend
method does perform 2 a deep copy when a true value is passed 1 as the initial argument:
var a =[[1], [2], [3]];
var b = $.extend(true, [], a);
b.shift().shift();
// a is still [[1], [2], [3]]
$.extend(true, [], [['a', ['c']], 'b'])
That should do it for you.
0
I realize you're looking for a "deep" copy of an array, but if you just have a single level array you can use this:
Copying a native JS Array is easy. Use the 5 Array.slice() method which creates a copy of part/all 4 of the array.
var foo = ['a','b','c','d','e'];
var bar = foo.slice();
now foo and bar are 5 member 3 arrays of 'a','b','c','d','e'
of course bar 2 is a copy, not a reference... so if you 1 did this next...
bar.push('f');
alert('foo:' + foo.join(', '));
alert('bar:' + bar.join(', '));
you would now get:
foo:a, b, c, d, e
bar:a, b, c, d, e, f
Everything in JavaScript is pass by reference, so 4 if you want a true deep copy of the objects 3 in the array, the best method I can think 2 of is to serialize the entire array to JSON 1 and then de-serialize it back.
If you want to use pure JavaScript then 1 try this:
var arr=["apple","ball","cat","dog"];
var narr=[];
for(var i=0;i<arr.length;i++){
narr.push(arr[i]);
}
alert(narr); //output: apple,ball,vat,dog
narr.push("elephant");
alert(arr); // output: apple,ball,vat,dog
alert(narr); // apple,ball,vat,dog,elephant
how about complex types? when array contains 3 objects... or any else
My variant:
Object.prototype.copy = function(){
var v_newObj = {};
for(v_i in this)
v_newObj[v_i] = (typeof this[v_i]).contains(/^(array|object)$/) ? this[v_i].copy() : this[v_i];
return v_newObj;
}
Array.prototype.copy = function(){
var v_newArr = [];
this.each(function(v_i){
v_newArr.push((typeof v_i).contains(/^(array|object)$/) ? v_i.copy() : v_i);
});
return v_newArr;
}
It's not 2 final version, just an idea.
PS: method each 1 and contains are prototypes also.
I've come across this "deep object 3 copy" function that I've found handy 2 for duplicating objects by value. It doesn't 1 use jQuery, but it certainly is deep.
http://www.overset.com/2007/07/11/javascript-recursive-object-copy-deep-object-copy-pass-by-value/
I plan on releasing this code in the next 6 version of jPaq, but until then, you can use 5 this if your goal is to do a deep copy of 4 arrays:
Array.prototype.clone = function(doDeepCopy) {
if(doDeepCopy) {
var encountered = [{
a : this,
b : []
}];
var item,
levels = [{a:this, b:encountered[0].b, i:0}],
level = 0,
i = 0,
len = this.length;
while(i < len) {
item = levels[level].a[i];
if(Object.prototype.toString.call(item) === "[object Array]") {
for(var j = encountered.length - 1; j >= 0; j--) {
if(encountered[j].a === item) {
levels[level].b.push(encountered[j].b);
break;
}
}
if(j < 0) {
encountered.push(j = {
a : item,
b : []
});
levels[level].b.push(j.b);
levels[level].i = i + 1;
levels[++level] = {a:item, b:j.b, i:0};
i = -1;
len = item.length;
}
}
else {
levels[level].b.push(item);
}
if(++i == len && level > 0) {
levels.pop();
i = levels[--level].i;
len = levels[level].a.length;
}
}
return encountered[0].b;
}
else {
return this.slice(0);
}
};
The following is an example of how 3 to call this function to do a deep copy 2 of a recursive array:
// Create a recursive array to prove that the cloning function can handle it.
var arrOriginal = [1,2,3];
arrOriginal.push(arrOriginal);
// Make a shallow copy of the recursive array.
var arrShallowCopy = arrOriginal.clone();
// Prove that the shallow copy isn't the same as a deep copy by showing that
// arrShallowCopy contains arrOriginal.
alert("It is " + (arrShallowCopy[3] === arrOriginal)
+ " that arrShallowCopy contains arrOriginal.");
// Make a deep copy of the recursive array.
var arrDeepCopy = arrOriginal.clone(true);
// Prove that the deep copy really works by showing that the original array is
// not the fourth item in arrDeepCopy but that this new array is.
alert("It is "
+ (arrDeepCopy[3] !== arrOriginal && arrDeepCopy === arrDeepCopy[3])
+ " that arrDeepCopy contains itself and not arrOriginal.");
You can play around 1 with this code here at JS Bin.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.