Самый быстрый способ продублировать массив в JavaScript - слайс против цикла 'for' - PullRequest
556 голосов
/ 20 октября 2010

Для того, чтобы продублировать массив в JavaScript: что из следующего быстрее использовать?

Метод среза

var dup_array = original_array.slice();

For петля

for(var i = 0, len = original_array.length; i < len; ++i)
   dup_array[i] = original_array[i];

Я знаю, что оба способа делают только поверхностную копию : если original_array содержит ссылки на объекты, объекты не будут клонированы, а будут скопированы только ссылки, и поэтому оба массива будут иметь ссылки на одни и те же объекты. Но суть этого вопроса не в этом.

Я спрашиваю только о скорости.

Ответы [ 17 ]

6 голосов
/ 28 апреля 2014

Существует гораздо более чистое решение:

var srcArray = [1, 2, 3];
var clonedArray = srcArray.length === 1 ? [srcArray[0]] : Array.apply(this, srcArray);

Требуется проверка длины, поскольку конструктор Array ведет себя по-разному, когда он вызывается с одним аргументом.

6 голосов
/ 27 августа 2015

Как сказал @Dan: «Этот ответ быстро устареет. Используйте тесты , чтобы проверить реальную ситуацию», есть один конкретный ответ от jsperf, который не имеет ответа для себя: while * * 1005

var i = a.length;
while(i--) { b[i] = a[i]; }
У

было 960 589 операций в секунду с разгоном a.concat() при 578 129 операций в секунду, что составляет 60%.

Это последний Firefox (40) 64 бит.


@ aleclarson создал новый, более надежный тест.

6 голосов
/ 20 октября 2010

Взгляните на: ссылка . Дело не в скорости, а в комфорте. Кроме того, как вы можете видеть, вы можете использовать только slice (0) на примитивных типах .

Чтобы сделать независимую копию массива, а не копию ссылки на него, вы можете использовать метод среза массива.

Пример:

Чтобы сделать независимую копию массива, а не копию ссылки на него, вы можете использовать метод среза массива.

var oldArray = ["mip", "map", "mop"];
var newArray = oldArray.slice();

Чтобы скопировать или клонировать объект:

function cloneObject(source) {
    for (i in source) {
        if (typeof source[i] == 'source') {
            this[i] = new cloneObject(source[i]);
        }
        else{
            this[i] = source[i];
  }
    }
}

var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
var obj2= new cloneObject(obj1);

Источник: ссылка

5 голосов
/ 18 ноября 2015

Зависит от длины массива. Если длина массива <= 1 000 000, методы <code>slice и concat занимают примерно одинаковое время. Но когда вы даете более широкий диапазон, выигрывает метод concat.

Например, попробуйте этот код:

var original_array = [];
for(var i = 0; i < 10000000; i ++) {
    original_array.push( Math.floor(Math.random() * 1000000 + 1));
}

function a1() {
    var dup = [];
    var start = Date.now();
    dup = original_array.slice();
    var end = Date.now();
    console.log('slice method takes ' + (end - start) + ' ms');
}

function a2() {
    var dup = [];
    var start = Date.now();
    dup = original_array.concat([]);
    var end = Date.now();
    console.log('concat method takes ' + (end - start) + ' ms');
}

function a3() {
    var dup = [];
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup.push(original_array[i]);
    }
    var end = Date.now();
    console.log('for loop with push method takes ' + (end - start) + ' ms');
}

function a4() {
    var dup = [];
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup[i] = original_array[i];
    }
    var end = Date.now();
    console.log('for loop with = method takes ' + (end - start) + ' ms');
}

function a5() {
    var dup = new Array(original_array.length)
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup.push(original_array[i]);
    }
    var end = Date.now();
    console.log('for loop with = method and array constructor takes ' + (end - start) + ' ms');
}

a1();
a2();
a3();
a4();
a5();

Если вы установите длину original_array равным 1 000 000, метод slice и метод concat занимают примерно одно и то же время (3-4 мс, в зависимости от случайных чисел).

Если вы установите длину original_array равным 10 000 000, то метод slice займет более 60 мс, а метод concat - более 20 мс.

4 голосов
/ 16 декабря 2017
Способ

ECMAScript 2015 с оператором Spread:

Основные примеры:

var copyOfOldArray = [...oldArray]
var twoArraysBecomeOne = [...firstArray, ..seccondArray]

Попробуйте в консоли браузера:

var oldArray = [1, 2, 3]
var copyOfOldArray = [...oldArray]
console.log(oldArray)
console.log(copyOfOldArray)

var firstArray = [5, 6, 7]
var seccondArray = ["a", "b", "c"]
var twoArraysBecomOne = [...firstArray, ...seccondArray]
console.log(twoArraysBecomOne);

Ссылки

3 голосов
/ 16 августа 2017

Простое решение:

original = [1,2,3]
cloned = original.map(x=>x)
2 голосов
/ 07 июня 2019
        const arr = ['1', '2', '3'];

         // Old way
        const cloneArr = arr.slice();

        // ES6 way
        const cloneArrES6 = [...arr];

// But problem with 3rd approach is that if you are using muti-dimensional 
 // array, then only first level is copied

        const nums = [
              [1, 2], 
              [10],
         ];

        const cloneNums = [...nums];

// Let's change the first item in the first nested item in our cloned array.

        cloneNums[0][0] = '8';

        console.log(cloneNums);
           // [ [ '8', 2 ], [ 10 ], [ 300 ] ]

        // NOOooo, the original is also affected
        console.log(nums);
          // [ [ '8', 2 ], [ 10 ], [ 300 ] ]

Итак, чтобы избежать этих сценариев, используйте

        const arr = ['1', '2', '3'];

        const cloneArr = Array.from(arr);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...