在JavaScript中复制任意n维数组?

时间:2012-06-08 00:29:48

标签: javascript arrays deep-copy

我基本上在寻找一个通用函数副本(数组),它将返回相同的n维数组,而不会引用前一个数组。

4 个答案:

答案 0 :(得分:5)

这适用于数组,它不适用于嵌套对象(不是数组):

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;
}

像这样使用:

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

var new_arr = copy(arr);

答案 1 :(得分:1)

使用jQuery(适用于数组和“普通”对象):

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]]

或JSON direct(如果所有对象都是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]]

较旧版本的IE(8?7?)需要一个垫片用于JSON对象。

答案 2 :(得分:0)

我只想补充Paulpro的答案。请注意,这与他的答案完全相同,只是我将副本(new_arr [i])更改为复制(arr [i]),将new_arr.length更改为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;
}

copy(new_arr [i])工作的原因是因为.slice复制了arr [i]指向的东西,使它们相等。

此外,尽管Paulpro的答案适用于所有情况,但如果多维数组的每个维度的每个成员都是一个数组或非数组,那么只需切片非数组维度就可以提高效率。 我的意思是复制指针数组有什么意义,这些指针只会被下面的递归覆盖?

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;
}

答案 3 :(得分:0)

这是克隆多维数组的解决方案;实际上我必须发明Array.prototype.clone()才能发明一个函数来生成N维数组并用值初始化它。



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));