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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35504310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:49:17  来源:igfitidea点击:

Deep copy an array in Angular 2 + TypeScript

javascripttypescriptangular

提问by Joel Almeida

I have an array of objects that is an input. Lets call it content.

我有一个作为输入的对象数组。让我们称之为content

When trying to deep copy it, it still has a reference to the previous array.

在尝试对其进行深度复制时,它仍然具有对前一个数组的引用。

I need to duplicate that input array, and change one property of the duplicated part.

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

So long I've tried different methods that weren't successful.

长期以来,我尝试了不同的方法,但都没有成功。

ES6 way:

ES6方式:

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

The sliceway:

slice方式:

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

In both of them all the objects inside the array have status: 'Default'.

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

What's the best approach to deep copy the array in Angular 2?

在 Angular 2 中深度复制数组的最佳方法是什么?

回答by YD1m

Check this:

检查这个:

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

回答by Cameron Gilbert

Simple:

简单的:

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

回答by Joel Almeida

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

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

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

回答by kabus

This is working for me:

这对我有用:

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

回答by BogdanC

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

使用 lodash 的 cloneDeep 方法来深度复制内部具有嵌套对象的对象的一种干净方法。

For Angular, you can do it like this:

对于 Angular,你可以这样做:

Install lodash with yarn add lodashor npm install lodash.

使用yarn add lodash或安装 lodash npm install lodash

In your component, import cloneDeepand use it:

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

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

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

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

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

我还在这里写了一篇文章,如果您需要更深入地了解为什么使用 lodash 的 cloneDeep。

回答by Alexei

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

这是DariaTypeScript 2.1开始工作的建议(请参阅问题的评论),并且基本上克隆了数组中的每个元素

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

回答by Alex Beugnet

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

回答by Erik Vullings

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.

或者,您可以使用 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;
};

回答by Riya Goel

you can use use JQuery for deep copying :

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

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

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