J'ai un tableau d'objets qui est une entrée. Permet de l'appeler content
.
En essayant de le copier en profondeur, il a toujours une référence au tableau précédent.
Je dois dupliquer ce tableau d'entrée et modifier une propriété de la partie dupliquée.
Si longtemps que j'ai essayé différentes méthodes qui ont échoué.
Façon ES6:
public duplicateArray() {
arr = [...this.content]
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
La manière slice
:
public duplicateArray() {
arr = this.content.slice(0);
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
Dans les deux, tous les objets du tableau ont status: 'Default'
.
Quelle est la meilleure approche pour copier en profondeur le tableau dans Angular 2?
Vérifie ça:
let cloned = source.map(x => Object.assign({}, x));
Simple:
let objCopy = JSON.parse(JSON.stringify(obj));
Cela fonctionne pour moi:
this.listCopy = Object.assign([], this.list);
La seule solution que j'ai trouvée (presque instantanément après avoir posé la question) est de parcourir le tableau et d'utiliser Object.assign()
Comme ça:
public duplicateArray() {
let arr = [];
this.content.forEach((x) => {
arr.Push(Object.assign({}, x));
})
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
Je sais que ce n'est pas optimal. Et je me demande s’il existe de meilleures solutions.
Une méthode propre de copie en profondeur des objets contenant des objets imbriqués consiste à utiliser la méthode cloneDeep de lodash.
Pour Angular, vous pouvez le faire comme ceci:
Installez lodash avec yarn add lodash
ou npm install lodash
.
Dans votre composant, importez cloneDeep
et utilisez-le:
import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);
C'est seulement 18kb ajoutés à votre construction, ce qui en vaut la peine.
J'ai également écrit un article ici , si vous avez besoin d'informations supplémentaires sur l'utilisation de cloneDeep de lodash.
Voici le mien. Ne fonctionne pas pour les cas complexes, mais pour un simple tableau d'objets, c'est suffisant.
deepClone(oldArray: Object[]) {
let newArray: any = [];
oldArray.forEach((item) => {
newArray.Push(Object.assign({}, item));
});
return newArray;
}
Ceci est une suggestion de Daria
(voir le commentaire sur la question) qui fonctionne à partir de TypeScript 2.1 et fondamentalement clone chaque élément du tableau :
this.clonedArray = theArray.map(e => ({ ... e }));
Vous pouvez également utiliser le projet GitHub ts-deepcopy , également disponible sur npm, pour cloner votre objet, ou simplement inclure l'extrait de code ci-dessous.
/**
* 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([]);