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