Подтвердить что ты не робот

Глубоко скопируйте массив в Angular 2 + TypeScript

У меня есть массив объектов, который является входом. Позволяет называть его 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?

4b9b3361

Ответ 1

Проверьте это:

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

Ответ 2

Простой:

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

Ответ 3

Единственное решение, которое я нашел (почти сразу после публикации вопроса), - это цикл через массив и использование 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

Это работает для меня:

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

Ответ 5

Чистый способ глубокого копирования объектов, содержащих вложенные объекты, - это использование метода lodash cloneDeep.

Для Angular вы можете сделать это так:

Установить lodash с yarn add lodash или npm install lodash.

В свой компонент импортируйте cloneDeep и используйте его:

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

Это только 18 КБ, добавленных к вашей сборке, что хорошо для выгоды.

Я также написал статью здесь, если вам нужно больше понять, почему вы используете lodash cloneDeep.

Ответ 6

Я мог бы дать прямой ответ, но тогда я не был бы прав, поэтому

Решите для себя после прочтения этого, этого, это и .

Но одна вещь, которую я могу вам сказать, это то, что в Typescript/Angular нет ничего, что было бы быстрее, чем Vanilla Javascript.

Ответ 8

Вот мой собственный. Не работает для сложных случаев, но для простого массива объектов это достаточно хорошо.

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

Ответ 9

Для меня назначение объекта didnt не работает ни функция duplicateArray, единственное, что работало для меня, это:

let object2 = Object.freeze(Object.assign({}, object1));
object2.likes = 8; // fails silently in non-strict mode & throws error in strict mode
console.log(object1.likes); // writes 7
console.log(object2.likes); // writes 7

Ответ 10

Для этого я бы использовал метод cloneDeep из Lodash.

Ответ 11

let originalArray :string[]  = ['one', 'two', 'Sc-fi'];
let cloneArray :string[]  = originalArray.concat([]);

Ответ 12

В качестве альтернативы вы можете использовать проект 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;
};

Ответ 13

let newArr = arr.slice();

Так копируются массивы в JS. Не нужно придумывать что-то новое!

Ответ 14

вы можете использовать JQuery для глубокого копирования:

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

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