在 Angular 2 + TypeScript 中深度复制数组

Deep copy an array in Angular 2 + TypeScript

本文关键字:深度 复制数组 TypeScript Angular      更新时间:2023-09-26

我有一个对象数组,它是一个输入。让我们称之为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 中深度复制数组的最佳方法是什么?

检查这个:

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

简单:

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

这也适用于(仅适用于数组)

let objCopy2 = obj.slice()
这是

Daria的建议(见对问题的评论),它从TypeScript 2.1开始工作,基本上从数组中克隆每个元素:

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

我有用:

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

我找到的唯一解决方案(几乎在发布问题后立即)是遍历数组并使用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);
}

我知道这不是最佳的。我想知道是否有更好的解决方案。

深层复制内部嵌套对象的对象的一种干净方法是使用 lodash 的克隆深度方法。

对于 Angular,你可以这样做:

安装带有yarn add lodashnpm install lodash的 lodash

在组件中,导入cloneDeep并使用它:

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

它只增加了 18kb 到您的构建中,非常值得

我也在这里写了一篇文章,如果你需要更多关于为什么使用lodash的cloneDeep的见解。

我在角度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
这是我

自己的。不适用于复杂情况,但对于简单的对象数组,它就足够了。

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

或者,您可以使用 GitHub 项目 ts-deepcopy(也可以在 npm 上使用)来克隆您的对象,或者只包含下面的代码片段。

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

您可以使用JQuery进行深度复制:

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