Copying an array of objects into another array in

2020-02-03 05:57发布

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

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.

9条回答
Ridiculous、
2楼-- · 2020-02-03 06:16

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)::

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.

查看更多
虎瘦雄心在
3楼-- · 2020-02-03 06:24

For this i use the new ECMAScript 6 Object.assign method :

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, ...)
查看更多
趁早两清
4楼-- · 2020-02-03 06:26

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

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

查看更多
登录 后发表回答