Copia in profondità una matrice in Angular 2 + TypeScript

Ho una matrice di oggetti che è un input. Lo chiamiamo content .

Quando si tenta di copiarlo in profondità, ha ancora un riferimento alla matrice precedente.

Devo duplicare quell’array di input e modificare una proprietà della parte duplicata.

Per tanto tempo ho provato diversi metodi che non hanno avuto successo.

Modo ES6:

 public duplicateArray() { arr = [...this.content] arr.map((x) => {x.status = DEFAULT}); return this.content.concat(arr); } 

La via della slice :

 public duplicateArray() { arr = this.content.slice(0); arr.map((x) => {x.status = DEFAULT}); return this.content.concat(arr); } 

In entrambi, tutti gli oggetti all’interno dell’array hanno lo status: 'Default' .

Qual è l’approccio migliore per copiare in profondità la matrice in Angular 2?

Controllare questo:

  let cloned = source.map(x => Object.assign({}, x)); 

Semplice:

 let objCopy = JSON.parse(JSON.stringify(obj)); 

Questo funziona per me:

 this.listCopy = Object.assign([], this.list); 

L’unica soluzione che ho trovato (quasi immediatamente dopo aver postato la domanda), è di scorrere l’array e usare Object.assign()

Come questo:

 public duplicateArray() { let arr = []; this.content.forEach((x) => { arr.push(Object.assign({}, x)); }) arr.map((x) => {x.status = DEFAULT}); return this.content.concat(arr); } 

So che questo non è ottimale. E mi chiedo se ci sono soluzioni migliori.

Un modo pulito per copiare in profondità oggetti con oggetti nidificati all’interno è usando il metodo cloneDeep di lodash.

Per Angular, puoi farlo in questo modo:

Installare lodash con yarn add lodash o npm install lodash .

Nel tuo componente, importa cloneDeep e cloneDeep :

 import * as cloneDeep from 'lodash/cloneDeep'; ... clonedObject = cloneDeep(originalObject); 

È solo 18kb aggiunto alla tua build, vale la pena per i benefici.

Ho anche scritto un articolo qui , se hai bisogno di maggiori informazioni sul perché usare il cloneDeep di lodash.

Ecco il mio. Non funziona per casi complessi, ma per una semplice serie di oggetti, è abbastanza buono.

  deepClone(oldArray: Object[]) { let newArray: any = []; oldArray.forEach((item) => { newArray.push(Object.assign({}, item)); }); return newArray; } 

puoi usare JQuery per la copia profonda:

 var arr =[['abc'],['xyz']]; var newArr = $.extend(true, [], arr); newArr.shift().shift(); console.log(arr); //arr still has [['abc'],['xyz']] 

Vorrei cloneDeep method di Lodash per questo.

 let originalArray :string[] = ['one', 'two', 'Sc-fi']; let cloneArray :string[] = originalArray.concat([]); 

In alternativa, puoi usare il progetto GitHub ts-deepcopy , che è anche disponibile su npm, per clonare il tuo object, o semplicemente includere lo snippet di codice qui sotto.

 /** * 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 = (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(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(cp[k]); }); return cp as T; } return target; }; 

Questo è il suggerimento di Daria (vedi il commento alla domanda) che funziona partendo da TypeScript 2.1 e fondamentalmente clona ogni elemento dell’array :

 this.clonedArray = theArray.map(e => ({ ... e }));