用角度2 + 字体脚本深度复制一个数组

我有一个对象数组,它是一个输入。让我们称之为 content

当试图深度复制它时,它仍然有一个对前一个数组的引用。

我需要复制那个输入数组,并更改复制部分的一个属性。

长久以来,我尝试了很多不成功的方法。

ES6方法:

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

slice方式:

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

在这两个对象中,数组中的所有对象都具有 status: 'Default'

在角度2中深拷贝数组的最佳方法是什么?

141155 次浏览

The only solution I've found (almost instantly after posting the question), is to loop through the array and use Object.assign()

Like this:

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

I know this is not optimal. And I wonder if there's any better solutions.

Here is my own. Doesn't work for complex cases, but for a simple array of Objects, it's good enough.

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

Check this:

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

This is working for me:

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

you can use use JQuery for deep copying :

var arr =[['abc'],['xyz']];
var newArr = $.extend(true, [], arr);
newArr.shift().shift();


console.log(arr); //arr still has [['abc'],['xyz']]

Simple:

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

This Also Works (Only for Arrays)

let objCopy2 = obj.slice()

A clean way of deep copying objects having nested objects inside is by using lodash's cloneDeep method.

For Angular, you can do it like this:

Install lodash with yarn add lodash or npm install lodash.

In your component, import cloneDeep and use it:

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

It's only 18kb added to your build, well worth for the benefits.

I've also written an article here, if you need more insight on why using lodash's cloneDeep.

Alternatively, you can use the GitHub project ts-deepcopy, which is also available on npm, to clone your object, or just include the code snippet below.

/**
* 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;
};

This is Daria's suggestion (see comment on the question) which works starting from TypeScript 2.1 and basically clones each element from the array:

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

I found deep copy method in angular devkit, It's very normal, so... maybe you can just implement yourself or use that.

I prefer to use loadash, there a lot of objects and array operation methods that can use.

import { deepCopy } from '@angular-devkit/core/src/utils/object';


export class AppComponent {
source = {
....
}
constructor() {
const newObject = deepCopy(this.source);
}
}
Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.1000.8
@angular-devkit/build-angular     0.1000.8
@angular-devkit/build-optimizer   0.1000.8
@angular-devkit/build-webpack     0.1000.8
@angular-devkit/core              10.0.8
@angular-devkit/schematics        10.0.8
@angular/cli                      10.0.8
@ngtools/webpack                  10.0.8
@schematics/angular               10.0.8
@schematics/update                0.1000.8
rxjs                              6.5.5
typescript                        3.9.7
webpack                           4.43.0