Лучший способ сплайсирования массива в массив в 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/