关于创建多维数组的副本,而不是引用-javascript

Create copy of multi-dimensional array, not reference - JavaScript

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is the most efficient way to clone a JavaScript object?

这也被称为"深度复制",我在上面找到了一些文章。最接近的似乎是这一个,但它是为jquery-我正在尝试这样做没有一个库。

我还看到,在两个地方,可以做如下事情:

1
arr2 = JSON.decode(JSON.encode(arr1));

但这显然是低效的。还可以单独循环和复制每个值,并在所有数组中循环。这看起来既累人又低效。

那么,复制一个javascript多维数组[[a],[b],]最有效的非库方法是什么?如果必要的话,我对"非IE"方法非常满意。

谢谢!


因为这听起来像是在处理一个深度未知的数组,但是在任何给定时间只需要在一个深度处理它们,那么使用.slice()将是简单而快速的。

1
2
3
4
var newArray = [];

for (var i = 0; i < currentArray.length; i++)
    newArray[i] = currentArray[i].slice();

或者使用.map()代替for循环:

1
2
3
var newArray = currentArray.map(function(arr) {
    return arr.slice();
});

因此,这将迭代当前数组,并构建嵌套数组的浅副本的新数组。当你进入下一个深度层次时,你也会做同样的事情。

当然,如果有数组和其他数据的混合,那么您需要在切片之前测试它是什么。


我不知道JSON.stringyJSON.parseencodedecode好多少,但你可以试试:

1
JSON.parse(JSON.stringify(array));

我发现了其他一些东西(尽管我会稍微修改一下):

http://www.xenoveritas.org/blog/xeno/the-correct-way-to-clone-javascript-arrays

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function deepCopy(obj) {
  if (typeof obj == 'object') {
    if (isArray(obj)) {
      var l = obj.length;
      var r = new Array(l);
      for (var i = 0; i < l; i++) {
        r[i] = deepCopy(obj[i]);
      }
      return r;
    } else {
      var r = {};
      r.prototype = obj.prototype;
      for (var k in obj) {
        r[k] = deepCopy(obj[k]);
      }
      return r;
    }
  }
  return obj;
}


当你要求性能时,我想你也会选择非通用的解决方案。要复制具有已知级别数的多维数组,您应该使用最简单的解决方案,一些嵌套for循环。对于二维数组,它只是如下所示:

1
2
3
4
var len = arr.length,
    copy = new Array(len); // boost in Safari
for (var i=0; i<len; ++i)
    copy[i] = arr[i].slice(0);

要扩展到更高维度的数组,请使用递归或嵌套for循环!

本机slice方法比自定义for循环更有效,但它不创建深度副本,因此我们只能在最低级别使用它。


任何不访问同一个节点两次的递归算法的效率都将与使用javascript(至少在浏览器中)所获得的效率相当——在某些情况下,在其他语言中,复制内存块可能会使您逃脱惩罚,但显然javascript没有这种能力。

我建议找一个已经完成了这项工作的人,并使用他们的实现来确保你做的对——只需要定义一次。