Лучший способ сплайсирования массива в массив в javascript

Есть ли лучший способ для объединения массива в другой массив в javascript

var string = 'theArray.splice('+start+', '+number+',"'+newItemsArray.join('","')+'");';
eval(string);

Ответ 1

Вы можете использовать apply, чтобы избежать eval:

var args = [start, number].concat(newItemsArray);
Array.prototype.splice.apply(theArray, args);

Функция apply используется для вызова другой функции с заданным контекстом и аргументами, представленными в виде массива, например:

Если мы вызываем:

var nums = [1,2,3,4];
Math.min.apply(Math, nums);

Функция apply выполнит:

Math.min(1,2,3,4);

Ответ 2

ОБНОВЛЕНИЕ: версия ES6

Если ваше кодирование в ES6 вы можете использовать "оператор распространения" (...)

array.splice(index, 0, ...arrayToInsert);

Чтобы узнать больше об операторе распространения см. Документацию Mozilla.

"Старый" путь ES5

Если вы оберните верхний ответ в функцию, вы получите это:

function insertArrayAt(array, index, arrayToInsert) {
    Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
}

Вы бы использовали это так:

var arr = ["A", "B", "C"];
insertArrayAt(arr, 1, ["x", "y", "z"]);
alert(JSON.stringify(arr)); // output: A, x, y, z, B, C

Вы можете проверить это в этом jsFiddle: http://jsfiddle.net/luisperezphd/Wc8aS/

Ответ 3

Этот вопрос действительно старый, но с ES6 существует более простой способ сделать это с помощью оператора spread:

sourceArray.splice(index, 0, ...insertedArray)

Если вы используете uncompiled javascript в браузере, обязательно проверьте, поддерживается ли он в вашем целевом браузере https://kangax.github.io/compat-table/es6/#test-spread_(...)_operator.


Кроме того, это может быть немного не в тему, но если вы не хотите или не должны изменять исходный массив, но можете использовать новый массив, рассмотрите этот подход:

mergedArray = sourceArray.slice(0, index).concat(insertedArray, sourceArray.slice(index))

Ответ 4

Вы также можете добавить такую ​​функцию в прототип Array, если хотите что-то, что почти похоже на метод сплайсинга. Например.

Array.prototype.spliceArray = function(index, n, array) {
    return Array.prototype.splice.apply(this, [index, n].concat(array));
}

Тогда использование просто было бы:

var array = ["A","B","C","","E","F"];

array.splice(3,1,"D");
// array is ["A","B","C","D","E","F"]

array.spliceArray(3,3,["1","2","3"]);
// array is ["A","B","C","1","2","3"]

Смотрите здесь: http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/

Некоторые примечания:

  • Функция splice изменяет массив непосредственно, но возвращает массив элементов, которые были удалены... не сплайсированный массив.
  • В то время как обычно не рекомендуется расширять основные классы javascript, это относительно мягко с большинством стандартных фреймворков.
  • Расширение Array не будет работать в тех случаях, когда используются специализированные классы массивов, такие как данные ImageData Uint8ClampedArray.

Ответ 5

Ответы выше, связанные с splice.apply и вставкой массива в один лайнер, взорвут стек в переполнении стека для большого массива. См. Пример здесь: http://jsfiddle.net/gkohen/u49ku99q/ Возможно, вам придется срезать и нажимать каждый элемент вставленной и оставшейся части исходного массива для его работы. Смотрите скрипту: http://jsfiddle.net/gkohen/g9abppgy/26/

Array.prototype.spliceArray = function(index, insertedArray) {
   var postArray = this.splice(index);
   inPlacePush(this, insertedArray);
   inPlacePush(this, postArray);

   function inPlacePush(targetArray, pushedArray) {
// Not using forEach for browser compatability
       var pushedArrayLength = pushedArray.length;
       for (var index = 0; index < pushedArrayLength; index++) {
           targetArray.push(pushedArray[index]);
       }
   }
}

Ответ 6

Здесь есть много умных ответов, но причина, по которой вы используете соединение, состоит в том, что он помещает элементы в текущий массив без создания другого. Если вам нужно создать массив для concat() чтобы вы могли использовать apply() то вы создаете 2 дополнительных массива мусора! Сорта побеждает всю цель написания эзотерического Javascript. Кроме того, если вы не заботитесь об этом (и вам следует) об использовании памяти, просто dest = src1.concat(src2); это бесконечно более читабельно. Итак, вот мое наименьшее количество строк, оставаясь эффективным ответом.

for( let item of src ) dest.push( item );

Или, если вы хотите его заполнить и вернуть немного лучшую поддержку браузера:

src.forEach( function( x ) { dest.push(x); });

Я уверен, что первый более производительный (это слово;), но не поддерживается во всех браузерах в дикой природе.

Ответ 7

Я хотел иметь функцию, которая будет принимать только часть исходного массива, поэтому у меня есть немного разные на основе ответа CMS

function spliceArray(array, index, howmany, source, start, end) {
    var arguments;
  if( source !== undefined ){
    arguments = source.slice(start, end);
    arguments.splice(0,0, index, howmany);
  } else{
   arguments = [index, howmany];
  }
    return Array.prototype.splice.apply(array, arguments)
}

Array.prototype.spliceArray = function(index, howmany, source, start, end) {
    return spliceArray(this, index, howmany, source, start, end);
}

Вы можете увидеть это: https://jsfiddle.net/matthewvukomanovic/nx858uz5/