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

Копирование массива объектов в другой массив в javascript

Как я могу скопировать каждый элемент массива (где элементы - объекты) в другой массив, чтобы они были полностью независимыми? Я не хочу изменять элемент в одном массиве, чтобы влиять на другой.

4b9b3361

Ответ 1

Если целевой массив еще не существует, вы можете использовать slice() или concat(); slice() (или slice(0), но аргумент по умолчанию 0), вероятно, более идиоматичен:

var destinationArray = sourceArray.slice(); // Probably more idiomatic
// or
var destinationArray = sourceArray.concat();

Как и в ES2015 (aka ES6), там также Array.from, который создает новый массив из любой подобной массиву вещи (включая фактический массив):

var destinationArray = Array.from(sourceArray);

(Array.from может быть отстроена/полина для старых движков JavaScript.)

После этого оба массива будут иметь одинаковое содержимое. Изменение одного массива не изменит другого. Естественно, если запись массива является объектом, запись для этого объекта в обоих массивах будет указывать на один и тот же объект; это не "глубокая" копия.

Если массив назначения существует и вы хотите добавить к нему содержимое исходного массива, вы можете использовать push:

destinationArray.push.apply(destinationArray, sourceArray);

Это работает, вызывая push в целевом массиве с использованием функции apply функций JavaScript, которая позволяет вам указывать аргументы для вызова функции как массива. push будет вызывать столько элементов, сколько имеет аргументы, поэтому он копирует элементы из исходного массива в целевой массив.

В ES2015 и более поздних версиях вы можете сделать этот фильтр с обозначением распространения (...):

destinationArray.push(...sourceArray);

Здесь версия ES5:

var source1, dest1, source2, dest2;

snippet.log("If dest doesn't exist yet:");
source1 = [1, 2, 3, 4];
dest1 = source1.slice(0);
snippet.log("[before change] source1 = " + source1.join(", "));
snippet.log("[before change] dest1 = " + dest1.join(", "));
source1[2] = "three";
dest1[3] = "four";
snippet.log("[after change] source1 = " + source1.join(", "));
snippet.log("[after change] dest1 = " + dest1.join(", "));

snippet.log("If dest already exists and we're just appending:");
source2 = [1, 2, 3, 4];
dest2 = ['a', 'b', 'c', 'd'];
snippet.log("[before append] source2 = " + source2.join(", "));
snippet.log("[before append] dest2 = " + dest2.join(", "));
dest2.push.apply(dest2, source2);
snippet.log("[before change] source2 = " + source2.join(", "));
snippet.log("[before change] dest2 = " + dest2.join(", "));
source2[2] = "three";
dest2[7] = "four";
snippet.log("[after change] source2 = " + source2.join(", "));
snippet.log("[after change] dest2 = " + dest2.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Ответ 2

Легкий способ получить эту работу:

var cloneArray = JSON.parse(JSON.stringify(originalArray));

У меня возникают проблемы с получением arr.concat() или arr.splice(0), чтобы получить глубокую копию. Над фрагментом отлично работает.

Ответ 3

var clonedArray = array.concat();

Ответ 4

Если вы хотите сохранить ссылку:

Array.prototype.push.apply(destinationArray, sourceArray);

Ответ 5

Отличный способ клонирования массива состоит из массива литерала и оператора с расширением. Это стало возможным благодаря ES2015.

let objArray = [{name:'first'}, {name:'second'}, {name:'third'}, {name:'fourth'}];

let clonedArr = [...objArray];

console.log(clonedArr) // [Object, Object, Object, Object]

Вы можете найти эту опцию копирования в документации MDN для операторов распространения https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Copy_an_array

Это также лучшая практика Airbnb. https://github.com/airbnb/javascript#es6-array-spreads

Примечание. Обычно операторы распространения в ES2015 идут на один уровень глубины при копировании массива. Поэтому они не подходят для копирования многомерных массивов.

Ответ 6

Я предлагаю использовать concat(), если вы используете nodeJS. Во всех остальных случаях я обнаружил, что slice(0) работает нормально.

Ответ 7

Есть две важные заметки.

  • Использование array.concat() не работает с использованием Angular 1.4.4 и jQuery 3.2.1 (это моя среда).
  • array.slice(0) - это объект. Поэтому, если вы сделаете что-то вроде newArray1 = oldArray.slice(0); newArray2 = oldArray.slice(0), два новых массива будут ссылаться только на один массив, а изменение одного повлияет на другое.

В качестве альтернативы использование newArray1 = JSON.parse(JSON.stringify(old array)) будет копировать только значение, поэтому каждый раз создается новый массив.