1

我基本上是在寻找一个通用函数 copy(array) ,它将返回相同的 n 维数组,而对前一个数组没有任何引用。

4

4 回答 4

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);
于 2012-06-08T00:37:58.243 回答
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 直接(如果所有对象都是 JSON 可化的):

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 对象的 shim。

于 2012-06-08T00:39:24.227 回答
0

我只是想补充一下 Paulpro 的答案。请注意,这与他的答案相同,只是我将 copy(new_arr[i]) 更改为 copy(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;
}
于 2013-12-08T14:39:37.203 回答
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));

于 2016-05-27T11:19:47.027 回答