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

时间:2012-12-07 03:28:13

标签: javascript arrays copy

  

可能重复:
  What is the most efficient way to clone a JavaScript object?

这也被称为“深度复制”,我发现了一些文章。最接近似乎是this one,但它适用于jQuery - 我试图在没有库的情况下这样做。

我在两个地方也看到过可以做的事情:

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

但这显然效率低下。也可以单独循环和复制每个值,并在所有数组中重复。这看起来很累人也很低效。

那么复制JavaScript多维数组[[a],[b],[c]]的最有效的非库方式是什么?如有必要,我对“非IE”方法非常满意。

谢谢!

4 个答案:

答案 0 :(得分:57)

因为听起来你正在处理一个阵列数组到某个未知的深度,但你只需要在任何给定时间在一个深度处理它们,那么它将变得简单快速地使用.slice()

var newArray = [];

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

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

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

因此,这会迭代当前的Array,并构建一个新的嵌套数组的浅拷贝数组。然后当你进入下一个深度时,你会做同样的事情。

当然,如果存在阵列和其他数据的混合,你需要在切片之前测试它是什么。

答案 1 :(得分:9)

我不确定JSON.stringyJSON.parseencodedecode好多少,但您可以尝试:

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

我找到的其他东西(虽然我稍微修改了一下):

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

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

答案 2 :(得分:6)

当你要求提高性能时,我想你也会采用非通用解决方案。要复制具有已知级别数的多维数组,您应该使用最简单的解决方案,一些嵌套的for循环。对于你的二维数组,它看起来就像这样:

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 method比自定义for循环更有效,但它不会创建深层副本,因此我们只能在最低级别使用它。

答案 3 :(得分:4)

任何两次不访问同一节点的递归算法都与javascript一样高效(至少在浏览器中) - 在某些其他语言的情况下,你可能会因复制内存而逃脱,但是javascript显然没有这种能力。

我建议找一个already done it的人并使用他们的实现来确保你做对了 - 它只需要定义一次。