2009-08-28 12 views

Respuesta

119

Usted puede utilizar apply para evitar eval:

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

La función apply se usa para llamar a otra función, con un contexto y argumentos dado, proporcionado como una matriz, por ejemplo:

Si llamamos:

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

La función de aplicación se ejecutará:

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

Aunque, resulta que necesito hacer Array.prototype.splice.apply (theArray, [start, number] .concat (newItemsArray)) ya que todos los argumentos, no solo algunos, deben estar en una matriz. – wheresrhys

+3

+1 para el patrón '[start, number] .concat (array)'. es ingenioso – Claudiu

+1

¿Alguien ha intentado ingresar una gran cantidad de elementos en Chrome? Alrededor de 130K elementos parece que tenemos la excepción de Stackoverflow. Ver: http://jsfiddle.net/DcHCY/ –

23

Wrap que en una función y se obtiene lo siguiente:

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

que usaría así:

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

Puede verificarlo en este jsFiddle: http://jsfiddle.net/luisperezphd/Wc8aS/

6

También puede agregar tal función al prototipo de matriz, si desea algo que sea casi idéntico al método de empalme. P.ej.

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

A continuación, el uso sería simplemente:

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"] 

verlo en acción aquí: http://jsfiddle.net/TheMadDeveloper/knv2f8bb/1/

Algunas notas:

  • La función splice modifica la matriz directamente, pero vuelve el conjunto de elementos que se eliminaron ... no el conjunto empalmado.
  • Si bien normalmente no se recomienda extender las clases básicas de JavaScript, esto es relativamente benigno con la mayoría de los marcos estándar.
  • Extender Array no funcionará en los casos en que se utilicen clases de matriz especializadas, como datos de ImageData Uint8ClampedArray.
1

Las respuestas anteriores que involucran empalmar.aplicar e insertar la matriz en una línea arruinarán la pila en un desbordamiento de pila para la matriz grande. Vea el ejemplo aquí: http://jsfiddle.net/gkohen/u49ku99q/ Es posible que tenga que cortar y empujar cada elemento de la parte insertada y restante de la matriz original para que funcione. Ver violín: 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

quería tener una función que tendría sólo una parte de la matriz de origen, así que tengo la mía ligeramente diferente sede fuera 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); 
} 

Se puede ver en: https://jsfiddle.net/matthewvukomanovic/nx858uz5/

6

Esta pregunta es muy antigua, pero con ES6, hay una forma más sencilla de hacerlo con el operador de propagación:

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

Si está utilizando javascript sin compilar en el navegador, asegúrese de comprobar si es compatible con su navegador de destino en https://kangax.github.io/compat-table/es6/#test-spread_(...)_operator.


Además, esto puede ser un poco fuera de tema, pero si usted no quiere o necesita para modificar la matriz original, pero podría utilizar una nueva matriz en lugar, considerar este enfoque:

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

Aquí hay muchas respuestas inteligentes, pero la razón por la que utiliza el empalme es para que coloque los elementos en la matriz actual sin crear otra. Si tiene que crear una matriz de concat() contra para que pueda usar apply(), ¡entonces está creando 2 matrices de basura adicionales! Sorta derrota el propósito de escribir Javascript esotérico. Además, si no te importa el uso de la memoria (y deberías) solo dest = src1.concat(src2); es infinitamente más legible Así que aquí está mi número más pequeño de líneas sin dejar de ser una respuesta eficiente.

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

O si desea polyfill y tener un poco de apoyo más atrás del navegador:

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

Estoy seguro que el primero es más performante (que es una palabra;), pero no compatible con todos los navegadores en la naturaleza.

Cuestiones relacionadas