Как скопировать массив 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>);