我有一个输入对象数组。让我们称之为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'
。
在Angular 2中深度复制数组的最佳方法是什么?
答案 0 :(得分:91)
检查一下:
let cloned = source.map(x => Object.assign({}, x));
答案 1 :(得分:33)
简单:
let objCopy = JSON.parse(JSON.stringify(obj));
答案 2 :(得分:14)
这对我有用:
this.listCopy = Object.assign([], this.list);
答案 3 :(得分:13)
我发现的唯一解决方案(在发布问题后几乎立即发现)是循环遍历数组并使用Object.assign()
像这样:
public duplicateArray() {
let arr = [];
this.content.forEach((x) => {
arr.push(Object.assign({}, x));
})
arr.map((x) => {x.status = DEFAULT});
return this.content.concat(arr);
}
我知道这不是最佳选择。我想知道是否有更好的解决方案。
答案 4 :(得分:8)
使用lodash的cloneDeep方法深入复制具有嵌套对象的对象的简洁方法。
对于Angular,你可以这样做:
使用yarn add lodash
或npm install lodash
安装lodash。
在您的组件中,导入cloneDeep
并使用它:
import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);
它只为您的构建添加了18kb,非常值得获益。
如果您需要更多地了解使用lodash的cloneDeep的原因,我还写了article here。
答案 5 :(得分:2)
这是this.clonedArray = theArray.map(e => ({ ... e }));
的建议(请参阅问题注释),从TypeScript 2.1开始,基本上是clones each element from the array:
{{1}}
答案 6 :(得分:1)
这是我自己的。不适用于复杂的情况,但对于一个简单的对象数组,它就足够了。
deepClone(oldArray: Object[]) {
let newArray: any = [];
oldArray.forEach((item) => {
newArray.push(Object.assign({}, item));
});
return newArray;
}
答案 7 :(得分:0)
let originalArray :string[] = ['one', 'two', 'Sc-fi'];
let cloneArray :string[] = originalArray.concat([]);
答案 8 :(得分:0)
或者,您可以使用npm上也提供的GitHub项目ts-deepcopy来克隆您的对象,或仅包含下面的代码段。
/**
* 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;
};
答案 9 :(得分:0)
let newArr = arr.slice();
这是在JS数组中复制的方式。无需考虑新事物!
答案 10 :(得分:0)
我在angular devkit中发现了深度复制方法,这很正常,所以...也许您可以自己实现或使用它。
我更喜欢使用loadash,可以使用很多对象和数组操作方法。
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
答案 11 :(得分:-1)
您可以使用JQuery进行深度复制:
var arr =[['abc'],['xyz']];
var newArr = $.extend(true, [], arr);
newArr.shift().shift();
console.log(arr); //arr still has [['abc'],['xyz']]