it-swarm.com.de

Kopieren Sie ein Array in Angular 2 + TypeScript

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?

48
Joel Almeida

Überprüfen Sie dies:

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

Einfach: 

let objCopy  = JSON.parse(JSON.stringify(obj));
24
Cameron Gilbert

Das funktioniert für mich: 

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

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.

13
Joel Almeida

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.

5
BogdanC

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;
  }
1
Alex Beugnet
let newArr = arr.slice();

So werden in JS Arrays kopiert. Keine Notwendigkeit, an etwas Neues zu denken!

1
Andris

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

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;
};
0
Erik Vullings
let originalArray :string[]  = ['one', 'two', 'Sc-fi'];
let cloneArray :string[]  = originalArray.concat([]);
0
Adam111p