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

Ran*_*all 59 javascript arrays copy

可能重复:
克隆JavaScript对象的最有效方法是什么?

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

我也在两个地方看到过这样的事情:

arr2 = JSON.decode(JSON.encode(arr1));
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

I H*_*azy 66

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

var newArray = [];

for (var i = 0; i < currentArray.length; i++)
    newArray[i] = currentArray[i].slice();
Run Code Online (Sandbox Code Playgroud)

或者使用.map()而不是for循环:

var newArray = currentArray.map(function(arr) {
    return arr.slice();
});
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这不是“深度”克隆!- 只有第二层深度被值复制。所有其他更深层次仍然通过引用复制,并且如果原始对象/数组发生变化,仍然会发生变化。如果您想要一个彻底克隆的对象,JSON 解析是一个更安全的选择。 (4认同)
  • 哇,地图真干净 (2认同)
  • 如今,您可以使用es6速记使其更加简洁。``var newArray = currentArray.map(arr =&gt; arr.slice());`'' (2认同)

Ian*_*Ian 9

我不知道如何更好地JSON.stringyJSON.parseencodedecode,但你可以尝试:

JSON.parse(JSON.stringify(array));
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)


Ber*_*rgi 6

As you asked for performance, I guess you also would go with a non-generic solution. To copy a multi-dimensional array with a known number of levels, you should go with the easiest solution, some nested for-loops. For your two-dimensional array, it simply would look like this:

var len = arr.length,
    copy = new Array(len); // boost in Safari
for (var i=0; i<len; ++i)
    copy[i] = arr[i].slice(0);
Run Code Online (Sandbox Code Playgroud)

To extend to higher-dimensional arrays, either use recursion or nested for loops!

The native slice method is more efficient than a custom for loop, yet it does not create deep copies, so we can use it only at the lowest level.