2009-08-28 2 views

ответ

119

Вы можете использовать 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); 

Функция применяется исполнят:

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

Хотя, оказывается, мне нужно сделать Array.prototype.splice.apply (theArray, [start, number] .concat (newItemsArray)), поскольку все аргументы, а не только некоторые, должны быть в одном массиве. – wheresrhys

+3

+1 для шаблона '[start, number] .concat (array)'. что отличное – Claudiu

+1

Кто-нибудь пытался ввести большое количество элементов в Chrome? Около 130 тыс. Элементов мы, похоже, получаем исключение Stackoverflow. Смотрите: http://jsfiddle.net/DcHCY/ –

23

Wrap, что в функцию, и вы получите это:

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/

6

Вы также можете добавить такую ​​функцию в прототип 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.
1

Ответы, которые связаны с 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]); 
     } 
    } 
} 
0

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

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/

6

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

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

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


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

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

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

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

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

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

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

Смежные вопросы