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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13756482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:49:11  来源:igfitidea点击:

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

javascriptarrayscopy

提问by Randy Hall

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

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

This is also referred to as "deep copying", which I've found some articles on. Closest seems to be this onebut it's for jQuery - I'm trying to do this without a library.

这也被称为“深度复制”,我找到了一些关于它的文章。最接近的似乎是这个,但它是针对 jQuery 的——我试图在没有库的情况下做到这一点。

I've also seen, in two places, that it's possible to do something like:

我还在两个地方看到可以执行以下操作:

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

But that's apparently inefficient. It's also possible to loop and copy each value individually, and recurs through all the arrays. That seems tiring and inefficient as well.

但这显然是低效的。也可以单独循环和复制每个值,并在所有数组中递归。这似乎也很累人,效率也很低。

So what's the most efficient, non-library way to copy a JavaScript multi-dimensional array [[a],[b],[c]]? I am completely happy with a "non-IE" method if necessary.

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

Thanks!

谢谢!

回答by I Hate Lazy

Since it sounds like you're dealing with an Array of Arrays to some unknown level of depth, but you only need to deal with them at one level deep at any given time, then it's going to be simple and fast to use .slice().

由于听起来您正在处理某个未知深度级别的数组数组,但您只需要在任何给定时间在一个深度级别处理它们,那么它的使用将变得简单而快速.slice()

var newArray = [];

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

Or using .map()instead of the forloop:

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

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

So this iterates the current Array, and builds a new Array of shallow copies of the nested Arrays. Then when you go to the next level of depth, you'd do the same thing.

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

Of course if there's a mixture of Arrays and other data, you'll want to test what it is before you slice.

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

回答by Ian

I'm not sure how much better JSON.stringifyand JSON.parsethan encodeand decode, but you could try:

我不确定JSON.stringifyandJSON.parseencodeand好多少decode,但你可以尝试:

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

Something else I found (although I'd modify it a little):

我发现的其他东西(虽然我会稍微修改一下):

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

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

回答by Bergi

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:

当您要求性能时,我想您也会使用非通用解决方案。要复制具有已知级别数的多维数组,您应该使用最简单的解决方案,一些嵌套的 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);

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

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

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

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

回答by Jeff

Any recursive algorithm that doesn't visit the same node twice will be about as efficient as you get with javascript (at least in a browser) - in certain situations in other languages you might get away with copying chucks of memory, but javascript obviously doesn't have that ability.

任何不会两次访问同一个节点的递归算法都将与使用 javascript 获得的效率差不多(至少在浏览器中) - 在其他语言的某些情况下,您可能会复制大量内存,但 javascript 显然不会没有那个能力

I'd suggest finding someone who's already done itand using their implementation to make sure you get it right - it only needs to be defined once.

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