Ich habe ein Array von Objekten, das eine Eingabe ist. Nennen wir es content
.
Wenn Sie versuchen, es tief zu kopieren, hat es immer noch einen Verweis auf das vorherige Array.
Ich muss dieses Eingabearray duplizieren und eine Eigenschaft des duplizierten Teils ändern.
So lange habe ich verschiedene Methoden ausprobiert, die nicht erfolgreich waren.
ES6 Weg:
public duplicateArray() {
arr = [...this.content]
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
Der slice
Weg:
public duplicateArray() {
arr = this.content.slice(0);
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
In beiden Objekten haben alle Objekte im Array status: 'Default'
.
Was ist der beste Ansatz, um das Array in Angular 2 tief zu kopieren?
Überprüfen Sie dies:
let cloned = source.map(x => Object.assign({}, x));
Einfach:
let objCopy = JSON.parse(JSON.stringify(obj));
Das funktioniert für mich:
this.listCopy = Object.assign([], this.list);
Die einzige Lösung, die ich gefunden habe (fast sofort nach dem Posten der Frage), besteht darin, das Array zu durchlaufen und Object.assign()
zu verwenden.
So was:
public duplicateArray() {
let arr = [];
this.content.forEach((x) => {
arr.Push(Object.assign({}, x));
})
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
Ich weiß das ist nicht optimal. Und ich frage mich, ob es bessere Lösungen gibt.
Eine saubere Methode zum tiefgreifenden Kopieren von Objekten mit verschachtelten Objekten ist die cloneDeep-Methode von lodash.
Für Angular können Sie es so machen:
Installieren Sie lodash mit yarn add lodash
oder npm install lodash
.
Importieren Sie in Ihrer Komponente cloneDeep
und verwenden Sie sie:
import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);
Es sind nur 18 KB in Ihrem Build, die sich für die Vorteile lohnen.
Ich habe auch einen Artikel hier geschrieben , wenn Sie mehr wissen wollen, warum lodash's cloneDeep verwendet wird.
Hier ist mein eigener. Funktioniert nicht für komplexe Fälle, aber für ein einfaches Array von Objekten ist es gut genug.
deepClone(oldArray: Object[]) {
let newArray: any = [];
oldArray.forEach((item) => {
newArray.Push(Object.assign({}, item));
});
return newArray;
}
let newArr = arr.slice();
So werden in JS Arrays kopiert. Keine Notwendigkeit, an etwas Neues zu denken!
Dies ist der Vorschlag von Daria
(siehe Kommentar zur Frage), der ab TypeScript 2.1 und grundsätzlich Klonen jedes Elements aus dem Array funktioniert:
this.clonedArray = theArray.map(e => ({ ... e }));
Alternativ können Sie das GitHub-Projekt ts-deepcopy verwenden, das auch bei npm verfügbar ist, um Ihr Objekt zu klonen, oder fügen Sie einfach den Code-Snippet ein.
/**
* Deep copy function for TypeScript.
* @param T Generic type of target/copied value.
* @param target Target value to be copied.
* @see Source project, ts-deepcopy https://github.com/ykdr2017/ts-deepcopy
* @see Code pen https://codepen.io/erikvullings/pen/ejyBYg
*/
export const deepCopy = <T>(target: T): T => {
if (target === null) {
return target;
}
if (target instanceof Date) {
return new Date(target.getTime()) as any;
}
if (target instanceof Array) {
const cp = [] as any[];
(target as any[]).forEach((v) => { cp.Push(v); });
return cp.map((n: any) => deepCopy<any>(n)) as any;
}
if (typeof target === 'object' && target !== {}) {
const cp = { ...(target as { [key: string]: any }) } as { [key: string]: any };
Object.keys(cp).forEach(k => {
cp[k] = deepCopy<any>(cp[k]);
});
return cp as T;
}
return target;
};
let originalArray :string[] = ['one', 'two', 'Sc-fi'];
let cloneArray :string[] = originalArray.concat([]);