簡體   English   中英

在javascript中將對象數組復制到另一個數組中(深度復制)

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

使用 slice(0) 和 concat() 將對象數組復制到 javascript 中的另一個數組中不起作用。

我嘗試了以下方法來測試我是否使用它獲得了預期的深層復制行為。 但是在我對復制的數組進行更改后,原始數組也會被修改。

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)

如何將一個數組深拷貝到另一個數組中,以便在更改副本數組時不會修改原始數組。

嘗試

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

嘗試以下

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

有關更多詳細信息,請查看此問題在 JavaScript 中深度克隆對象的最有效方法是什么?

如前所述, .slice .slice(0)將有效地克隆具有原始類型元素的數組。 但是,在您的示例tags數組中包含匿名對象。 因此,對克隆數組中這些對象的任何更改都會反映在tags數組中。

@dangh 上面的回復取消了對這些元素對象的引用並創建了新對象。

這是另一個解決類似情況的線程

使用 ES6 克隆對象數組的一個好方法是使用擴展語法:

const clonedArray = [...oldArray];

MDN

在一行中執行此操作的最簡單和樂觀的方法是使用 Underscore/Lodash

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

您只需要使用 '...' 符號。

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

當你有一個數組說 x 時,[...x] 創建一個包含所有 x 值的新數組。 請小心,因為此符號在對象上的工作方式略有不同。 它將對象拆分為所有的鍵值對。 因此,如果要將對象的所有鍵值對傳遞給函數,則只需傳遞 function({...obj})

同樣的問題發生在我身上。 我有來自服務的數據並保存到另一個變量。 每當我更新我的數組時,復制的數組也會更新。 舊代碼如下

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

因此,每當我更改 $scope.MyData 時,也會更改 $scope.MyDataOriginal。 我找到了一個解決方案,angular.copy right 代碼如下

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

我知道這是一個有點舊的帖子,但我很幸運找到了一種體面的方法來深度復制數組,即使是那些包含數組和對象的數組,甚至包含數組的對象也會被復制......我只能看到一個問題使用此代碼,如果您沒有足夠的內存,我可以看到這種阻塞在非常大的數組和對象數組上......但在大多數情況下它應該可以工作。 我在此處發布此內容的原因是它完成了按值而不是按引用復制對象數組的 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;
}

這個函數(Array.prototype.copy)在調用對象或數組時使用遞歸來調用它自己,並根據需要返回值。 這個過程非常快,並且完全符合您的要求,它按值對數組進行了深層復制...在 chrome 和 IE11 中進行了測試,並且可以在這兩個瀏覽器中使用。

用 JSON.parse 在 JavaScript 中深度復制數組的方法:

 let orginalArray= [ {firstName:"Choton", lastName:"Mohammad", age:26}, {firstName:"Mohammad", lastName:"Ishaque", age:26} ]; let copyArray = JSON.parse(JSON.stringify(orginalArray)); copyArray[0].age=27; console.log("copyArray",copyArray); console.log("orginalArray",orginalArray);

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

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

這個方法的第一個參數是要更新的數組,我們傳遞一個空對象,因為我們想要一個全新的對象,

您也可以添加其他要復制的對象:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM