it-swarm.com.de

Ein Array von Objekten in ein anderes Array in Javascript kopieren (Deep Copy)

Das Kopieren eines Arrays von Objekten in ein anderes Array in Javascript mit slice (0) und concat () funktioniert nicht.

Ich habe folgendes versucht, um zu testen, ob ich das erwartete Verhalten von Deep Copy mit dieser Funktion erhalte. Das ursprüngliche Array wird jedoch auch modifiziert, nachdem ich Änderungen am kopierten Array vorgenommen habe.

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)

Wie mache ich eine tiefe Kopie eines Arrays in ein anderes, so dass das ursprüngliche Array nicht geändert wird, wenn ich eine Änderung im Copy-Array vornehme.

18
jsbisht

Versuchen

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

Versuche Folgendes

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

Weitere Informationen finden Sie in dieser Frage. Wie kann ein Objekt in JavaScript tief geklont werden?

14
Marko

Wie bereits erwähnt, ist Here.slice(0) beim Klonen des Arrays mit primitiven Typelementen effektiv. In Ihrem Beispiel enthält das tags-Array anonyme Objekte. Daher werden alle Änderungen an diesen Objekten im geklonten Array im Array tags übernommen.

@Danghs Antwort oben entwertet diese Elementobjekte und erstellt neue. 

Hier ist ein anderer Thread, der eine ähnliche Situation anspricht

4
Bhanuprakash D

Eine schöne Möglichkeit, ein Array von Objekten mit ES6 zu klonen, ist die Spread-Syntax:

const clonedArray = [...oldArray];

MDN

3
Binaromong

Sie müssen nur die '...' - Notation verwenden.

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

Wenn Sie ein Array x sagen, erstellt [... x] ein neues Array mit allen Werten von x. Seien Sie vorsichtig, da diese Notation bei Objekten etwas anders funktioniert. Es teilt die Objekte in alle wichtigen Wertepaare auf. Wenn Sie also alle Schlüsselwertpaare eines Objekts in eine Funktion übergeben möchten, müssen Sie nur die Funktion ({... obj}) übergeben.

1
Anant Sinha

Die einfachste und optimistischste Vorgehensweise in einer einzigen Zeile ist die Verwendung von Underscore/Lodash

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

0
user8876438

Ich weiß, dass dies ein etwas älterer Post ist, aber ich hatte das Glück, Arrays, die Arrays enthalten, und Objekte und sogar Objekte, die Arrays enthalten, in einer guten Weise zu kopieren. Ich kann nur ein Problem sehen Mit diesem Code ist es möglich, wenn Sie nicht über genügend Speicher verfügen, ich kann dieses Würgen bei sehr großen Arrays und Objekten erkennen ... Aber meistens sollte es funktionieren. Der Grund, warum ich dies hier poste, ist, dass es die OP-Anfrage durchführt, um das Array der Objekte nach Wert und nicht nach Referenz zu kopieren ... also jetzt mit dem Code (die Prüfungen stammen von SO, die Hauptkopierfunktion, die ich selbst geschrieben habe, nicht.) dass jemand anderes wahrscheinlich noch nicht geschrieben hat, ich weiß es einfach nicht):

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

Diese Funktion (Array.prototype.copy) verwendet die Rekursion, um sich selbst aufzurufen, wenn ein Objekt oder Array aufgerufen wird, das die Werte nach Bedarf zurückgibt. Der Prozess ist anständig schnell und macht genau das, was Sie wollen, er macht eine tiefe Kopie eines Arrays nach Wert ... In Chrome getestet und IE11 und es funktioniert in diesen beiden Browsern. 

0
Jesse Fender

Das gleiche Problem passiert mir. Ich habe Daten vom Dienst und speichere in einer anderen Variablen. Jedes Mal, wenn ich mein Array aktualisiere, wird auch das kopierte Array aktualisiert. alter Code ist wie unten

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

Wann immer ich also $ scope.MyData ändere, ändere ich auch $ scope.MyDataOriginal. Ich habe eine Lösung gefunden, die eckigen.Code wie folgt kopiert

$scope.MyDataOriginal = angular.copy($scope.MyData);
0
Biby Cheriyan