Как скопировать массив js
Перейти к содержимому

Как скопировать массив js

  • автор:

Как скопировать массив js

У нас есть массив строк arr . Нужно получить отсортированную копию, но оставить arr неизменённым.

Создайте функцию copySorted(arr) , которая будет возвращать такую копию.

let arr = ["HTML", "JavaScript", "CSS"]; let sorted = copySorted(arr); alert( sorted ); // CSS, HTML, JavaScript alert( arr ); // HTML, JavaScript, CSS (без изменений)

Для копирования массива используем slice() и тут же – сортировку:

function copySorted(arr) < return arr.slice().sort(); >let arr = ["HTML", "JavaScript", "CSS"]; let sorted = copySorted(arr); alert( sorted ); alert( arr );

Простое клонирование/копирование массива в JavaScript

Чтобы клонировать/копировать содержимое массива, все, что вам нужно сделать, это вызвать метод slice, передав 0 в качестве первого аргумента:

var clone = myArray.slice(0); 

Код выше создает копию исходного массива; имейте в виду, если в вашем массиве существуют объекты — они хранятся как ссылки; т.е. код выше не делает “deep” клонирование содержимого массива.

Чтобы добавить копирование, как нативный метод к массивам, вы могли бы сделать что-то вроде этого:

Array.prototype.clone = function () < return this.slice(0); >; 

Давайте напишем рекурсивную функцию, чтобы копировать массив, который потенциально может иметь вложенные объекты или массивы:

function arrayClone (arr) < var i, copy; if (Array.isArray(arr)) < copy = arr.slice(0); for (i = 0; i < copy.length; i++) < copy[i] = arrayClone(copy[i]); >return copy; > else if (typeof arr === 'object') < throw 'Cannot clone array containing an object!'; >else < return arr; >> 

Если вы используете Underscore – можете сделать это еще короче:

function arrayClone (arr) < if (_.isArray(arr)) < return _.map(arr, arrayClone); >else if (typeof arr === 'object') < throw 'Cannot clone array containing an object!'; >else < return arr; >> 

С версии ECMAScript 2015 был введен метод Object.assign(), с его помощью глубокое клонирование можно реализовать еще проще:

var clone = Object.assign([], myArray); 

Заключение

Если вам нужно глубокое копирование произвольно-вложенных объектов и/или массивов, крошечный node-clone прекрасно с этим справиться. Он будет правильно обрабатывать даже копирование объектов с циклическими ссылками!

Источники

  • Clone Arrays with JavaScript
  • How to Clone a (Nested) Array in Javascript

Как сделать копию массива на js

Копию массива в js можно получить используя встроенный метод slice():

 [1, 2, 3] // убедится в том что это другой массив можно сравнив ссылки на массивы arr === copyArr // false 

В качестве альтернативы можно воспользоваться возможностями spread оператора:

 [1, 2, 3] arr === copyArr // false 

19 октября 2022

Можно несколькими способами сделать копию массива.

  • С помощью цикла for :
const array = [1, 2, 3, 'hello', true, [4, 5]]; const arrayCopy = []; for (let i = 0; i  array.length; i += 1)  arrayCopy[i] = array[i]; > console.log(arrayCopy); // => [1, 2, 3, 'hello', true, [4, 5]] // убеждаемся, что это другой массив console.log(array === arrayCopy); // => false 
  • С помощью метода map() :
const arrayCopy = array.map((element) => element); console.log(arrayCopy); // => [1, 2, 3, 'hello', true, [4, 5]] console.log(array === arrayCopy); // => false 
  • С помощью комбинации методов JSON.parse() и JSON.stringify() (подходит для глубокого копирования массивов и объектов):
const arrayCopy = JSON.parse(JSON.stringify(array)); console.log(arrayCopy); // => [1, 2, 3, 'hello', true, [4, 5]] console.log(array === arrayCopy); // => false 
  • С помощью метода concat() :
const arrayCopy = array.concat([]); console.log(arrayCopy); // => [1, 2, 3, 'hello', true, [4, 5]] console.log(array === arrayCopy); // => false 
  • С помощью метода Array.from() :
const arrayCopy = Array.from(array); console.log(arrayCopy); // => [1, 2, 3, 'hello', true, [4, 5]] console.log(array === arrayCopy); // => false 

Скопировать значение массива, а не ссылку на него

Здравствуйте! Скажите, а как можно скопировать в JavaScript массив так, чтобы, при изменении копии, оригинал не менялся? Например:

a = [0, 1, 2, 3] b = clone(a) b[0] = 10 a[0] == 0 // => true 

Можно ли реализовать такой метод clone ?
Отслеживать
задан 1 авг 2016 в 21:10
1,526 1 1 золотой знак 11 11 серебряных знаков 27 27 бронзовых знаков

6 ответов 6

Сортировка: Сброс на вариант по умолчанию

var a = [0, 1, 2, 3] var b = a.slice(0); b[0] = 10; console.log('a: ' + a); console.log('b: ' + b);

slice — возвращает поверхностную копию части массива в новый объект массива.

В данном случае с начала и до конца

Технически slice — наибыстрый путь, ОДНАКО это будет даже еще быстрее если добавить 0 — как начало «отрезания»

myArray.slice(0); 
myArray.slice(); 

. так говорят языки %)

Отслеживать
ответ дан 1 авг 2016 в 21:16
Алексей Шиманский Алексей Шиманский
72.7k 12 12 золотых знаков 92 92 серебряных знака 180 180 бронзовых знаков

Скажите, а как сделать так: a = [0, 1, 2, 3] change(a) a == [1, 2] // => true a = [3, 2, 1] b = какой_то_метод(a) change(b) b == [2, 1] // => true a == [3, 2, 1] // => true

1 авг 2016 в 22:08
Действительно быстрее 🙂
1 авг 2016 в 23:26

Замер производительности

В хроме slice(0) действительно немного быстрее, чем просто slice() и в 2 раза быстрее, чем concat . А вот Array.from даже concat у проигрывает в 10 раз — 3 секунды на миллион итераций о_О.

А вот Edge так не считает — там concat самый быстрый. А Array.from по-прежнему в 10 (с хвостиком) раз медленнее concat а — 1.4 секунды.

При запуске сниппета браузер повиснет на несколько секунд — это нормально.

function test(f) < var a = [0, 1, 2, 3]; var t = performance.now(); f(a); t = performance.now() - t; console.log((""+f).match(/var b = .*$/m)[0] + " // " + t.toFixed(3) + " ms"); >test(function testSlice(a) < for (var q=0; q>); test(function testSlice0(a) < for (var q=0; q>); test(function testConcat(a) < for (var q=0; q>); test(function testFrom(a) < for (var q=0; q>); test(function testAssign(a) < // Так делать не надо, просто для сравнения for (var q=0; q>); test(function testDesruct(a) < for (var q=0; q>);

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *