将对象数组复制到 javascript 中的另一个数组中(深度复制)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28482593/
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-23 01:51:36  来源:igfitidea点击:

Copying an array of objects into another array in javascript (Deep Copy)

javascriptarraysnode.jsgoogle-chromedeep-copy

提问by jsbisht

Copying an array of objects into another array in javascript using slice(0) and concat() doesnt work.

使用 slice(0) 和 concat() 将对象数组复制到 javascript 中的另一个数组中不起作用。

I have tried the following to test if i get the expected behaviour of deep copy using this. But the original array is also getting modified after i make changes in the copied array.

我尝试了以下方法来测试我是否使用它获得了深度复制的预期行为。但是在我对复制的数组进行更改后,原始数组也会被修改。

var tags = [];
for(var i=0; i<3; i++) {
    tags.push({
        sortOrder: i,
        type: 'miss'
    })
}
for(var tag in tags) { 
    if(tags[tag].sortOrder == 1) {
        tags[tag].type = 'done'
    }
}
console.dir(tags)

var copy = tags.slice(0)
console.dir(copy)

copy[0].type = 'test'
console.dir(tags)

var another = tags.concat()
another[0].type = 'miss'
console.dir(tags)

How can i do a deep copy of a array into another, so that the original array is not modified if i make a change in copy array.

我如何将一个数组深拷贝到另一个数组中,以便在我对复制数组进行更改时不会修改原始数组。

回答by dangh

Try

尝试

var copy = JSON.parse(JSON.stringify(tags));

回答by Marko

Try the following

尝试以下

// Deep copy
var newArray = jQuery.extend(true, [], oldArray);

For more details check this question out What is the most efficient way to deep clone an object in JavaScript?

有关更多详细信息,请查看此问题在 JavaScript 中深度克隆对象的最有效方法是什么?

回答by Bhanuprakash D

As mentioned Here.slice(0)will be effective in cloning the array with primitive type elements. However in your example tagsarray contains anonymous objects. Hence any changes to these objects in cloned array are reflected in tagsarray.

如前所述,Here.slice(0)将有效地克隆具有原始类型元素的数组。但是在您的示例tags数组中包含匿名对象。因此,对克隆数组中这些对象的任何更改都会反映在tags数组中。

@dangh's reply above derefences these element objects and create new ones.

@dangh 上面的回复取消了这些元素对象的引用并创建了新的对象。

Here is another threadaddressing similar situation

这是另一个解决类似情况的线程

回答by Binaromong

A nice way to clone an array of objects with ES6 is to use spread syntax:

使用 ES6 克隆对象数组的一个好方法是使用扩展语法:

const clonedArray = [...oldArray];

MDN

MDN

回答by user8876438

Easiest and the optimistic way of doing this in one single line is using Underscore/Lodash

在一行中执行此操作的最简单和乐观的方法是使用 Underscore/Lodash

let a = _.map(b, _.clone)

让 a = _.map(b, _.clone)

回答by Biby Cheriyan

Same issue happen to me. I have data from service and save to another variable. When ever I update my array the copied array also updated. old code is like below

同样的问题发生在我身上。我有来自服务的数据并保存到另一个变量。当我更新我的数组时,复制的数组也会更新。旧代码如下

//$scope.MyData get from service
$scope.MyDataOriginal = $scope.MyData;

So when ever I change $scope.MyData also change $scope.MyDataOriginal. I found a solution that angular.copy right code as below

因此,当我更改 $scope.MyData 时,也会更改 $scope.MyDataOriginal。我找到了一个解决方案,angular.copy 正确的代码如下

$scope.MyDataOriginal = angular.copy($scope.MyData);

回答by Jesse Fender

I know that this is a bit older post but I had the good fortune to have found a decent way to deep copy arrays, even those containing arrays, and objects, and even objects containing arrays are copied... I only can see one issue with this code is if you don't have enough memory I can see this choking on very large arrays of arrays and objects... But for the most part it should work. The reason that I am posting this here is that it accomplishes the OP request to copy array of objects by value and not by reference... so now with the code (the checks are from SO, the main copy function I wrote myself, not that some one else probably hasn't written before, I am just not aware of them)::

我知道这是一篇较旧的帖子,但我有幸找到了一种深度复制数组的体面方法,即使是那些包含数组和对象的对象,甚至包含数组的对象也被复制......我只能看到一个问题使用此代码,如果您没有足够的内存,我可以看到这种在非常大的数组和对象数组上窒息的情况……但在大多数情况下,它应该可以工作。我在这里发布的原因是它完成了按值而不是按引用复制对象数组的 OP 请求……所以现在使用代码(检查来自 SO,我自己编写的主要复制函数,而不是其他人可能以前没有写过,我只是不知道他们)::

var isArray = function(a){return (!!a) && (a.constructor===Array);}
var isObject = function(a){return (!!a) && (a.constructor===Object);}
Array.prototype.copy = function(){
    var newvals=[],
        self=this;
    for(var i = 0;i < self.length;i++){
        var e=self[i];
        if(isObject(e)){
            var tmp={},
                oKeys=Object.keys(e);
            for(var x = 0;x < oKeys.length;x++){
                var oks=oKeys[x];
                if(isArray(e[oks])){
                    tmp[oks]=e[oks].copy();
                } else { 
                    tmp[oks]=e[oks];
                }
            }
            newvals.push(tmp);
        } else {
            if(isArray(e)){
                newvals.push(e.copy());
            } else {
                newvals.push(e);
            }
        }
    }
    return newvals;
}

This function (Array.prototype.copy) uses recursion to recall it self when an object or array is called returning the values as needed. The process is decently speedy, and does exactly what you would want it to do, it does a deep copy of an array, by value... Tested in chrome, and IE11 and it works in these two browsers.

这个函数 (Array.prototype.copy) 在调用对象或数组时使用递归来调用它自己,并根据需要返回值。该过程相当快,并且完全按照您的意愿执行,它按值执行数组的深层复制...在 chrome 和 IE11 中进行了测试,并且可以在这两种浏览器中使用。

回答by Anant Sinha

You just need to use the '...' notation.

您只需要使用“...”符号。

// THE FOLLOWING LINE COPIES all elements of 'tags' INTO 'copy'
var copy = [...tags]

When you have an array say x, [...x] creates a new array with all the values of x. Be careful because this notation works slightly differently on objects. It splits the objects into all of its key, value pairs. So if you want to pass all the key value pairs of an object into a function you just need to pass function({...obj})

当你有一个数组 x 时,[...x] 创建一个包含 x 的所有值的新数组。请小心,因为此符号在对象上的作用略有不同。它将对象拆分为其所有的键值对。所以如果你想把一个对象的所有键值对传递给一个函数,你只需要传递 function({...obj})

回答by Chtiwi Malek

For this i use the new ECMAScript 6 Object.assignmethod :

为此,我使用新的 ECMAScript 6 Object.assign方法:

let oldObject = [1,3,5,"test"];
let newObject = Object.assign({}, oldObject)

the first argument of this method is the array to be updated, we pass an empty object because we want to have a completely new object,

这个方法的第一个参数是要更新的数组,我们传递一个空对象,因为我们想要一个全新的对象,

also you can add other objects to be copied too :

您也可以添加其他要复制的对象:

let newObject = Object.assign({}, oldObject, o2, o3, ...)