¿Cómo insertar un elemento en una matriz en un índice específico?

8 minutos de lectura

avatar de usuario de tags2k
etiquetas2k

Estoy buscando un método de inserción de matriz de JavaScript, al estilo de:

arr.insert(index, item)

Preferiblemente en jQuery, pero cualquier implementación de JavaScript funcionará en este punto.

  • Tenga en cuenta que JQuery es una biblioteca de manipulación de eventos y DOM, no un lenguaje propio. No tiene nada que ver con la manipulación de matrices.

    – Dominó

    18 de febrero de 2015 a las 15:36

  • api.jquery.com/jQuery.inArray no tiene nada que ver con el DOM o los eventos. jQuery se ha convertido en un conjunto de herramientas mixtas para el desarrollo de JS en el navegador, lo que lleva a las personas a esperar que tenga un método para todo.

    – Tim

    14 de abril de 2016 a las 8:14

  • @Tim, pero todavía no es un lenguaje propio (todavía hay algunas preguntas como “cómo sumar dos números en jQuery” aquí en SO)

    – Víctor

    7 mayo 2018 a las 13:31

  • @Victor No, y nunca lo será. jQuery fue útil y relevante, pero tuvo su día.

    – Tim

    8 de mayo de 2018 a las 6:17

  • Me molesta que el título de esta pregunta y el título de la página sean diferentes (jQuery vs. JS). Aparece de forma diferente en los resultados de búsqueda.

    – Andrés

    7 de junio de 2020 a las 0:14

Avatar de usuario de FrEsC 81
FRESC 81

Puede implementar el Array.insert método haciendo esto:

Array.prototype.insert = function ( index, ...items ) {
    this.splice( index, 0, ...items );
};

Entonces puedes usarlo como:

var arr = [ 'A', 'B', 'E' ];
arr.insert(2, 'C', 'D');

// => arr == [ 'A', 'B', 'C', 'D', 'E' ]

  • Para insertar varios elementos, puede utilizar Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }

    –Ryan Smith

    30 de mayo de 2014 a las 12:15


  • El problema de agregar cosas a la matriz es que la función se mostrará como un elemento cuando hagas for(i in arr) {…}

    – rep_movsd

    2 de julio de 2014 a las 9:38

  • Pero tenga en cuenta que no se recomienda extender los tipos nativos, ya que podría interferir con otro código o funcionalidad futura.

    – marsze

    21 de agosto de 2018 a las 9:48

  • No modifiques objetos que no te pertenecen

    –Luis Cabrera Benito

    19 de febrero de 2019 a las 18:09

  • No modifique los prototipos

    – satya164

    31 de mayo de 2019 a las 12:54

  • ¿Es esta una forma buena y segura de hacerlo? Pregunto porque esto parece tan elegante y conciso, pero ninguna otra respuesta toca esto. ¡La mayoría de ellos modifican el objeto prototipo!

    – otro desarrollador

    11 de diciembre de 2017 a las 9:32

  • @HarshKanchina Probablemente se deba a que la mayoría de las respuestas son anteriores a ES6, pero este enfoque es muy común ahora según mi experiencia.

    – gafi

    16 dic 2017 a las 22:35


  • Este enfoque siempre será más lento y peor que el empalme. No se deje engañar por la bonita sintaxis de azúcar o la popularidad entre otros desarrolladores equivocados (*tos* gafi *tos*). Asignar una matriz completamente nueva y descartar la matriz anterior es mucho más lento que modificar la matriz original. Si necesita una copia, llame al slice() antes splice(). Nunca use el ES6 para cosas tan triviales que se pueden hacer mucho mejor y mucho más limpias con otras API.

    – Jack G.

    19 de enero de 2021 a las 2:19

  • Debe explicar POR QUÉ debe evitar la mutación. ¿Es lento? Si es así, ¿cuánto más lento? ¿Vale la pena la “molestia” extra?

    – Daniel Testa

    25 de mayo de 2021 a las 9:34

  • @JackG no olvides eso slice() asignará una nueva matriz y, de hecho, splice() también asigna una nueva matriz, ya que devuelve una matriz de los elementos que se eliminaron (una matriz vacía en este caso). Ejecutar un punto de referencia en estos casos muestra que el empalme es más rápido (en ~30 %), pero estamos en el rango de millones de operaciones por segundo, así que a menos que su aplicación esté haciendo un lote de estas operaciones en un ciclo cerrado, no va a hacer ninguna diferencia.

    – nickf

    22 sep 2021 a las 9:00

Avatar de usuario de VisioN
Visión

Matriz personalizada insert métodos

1. Con múltiples argumentos y soporte de encadenamiento.

/* Syntax:
   array.insert(index, value1, value2, ..., valueN) */

Array.prototype.insert = function(index) {
    this.splice.apply(this, [index, 0].concat(
        Array.prototype.slice.call(arguments, 1)));
    return this;
};

Puede insertar múltiples elementos (como nativo splice hace) y admite el encadenamiento:

["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]

2. Con soporte de combinación y encadenamiento de argumentos de tipo matriz

/* Syntax:
   array.insert(index, value1, value2, ..., valueN) */

Array.prototype.insert = function(index) {
    index = Math.min(index, this.length);
    arguments.length > 1
        && this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
        && this.insert.apply(this, arguments);
    return this;
};

Puede fusionar matrices de los argumentos con la matriz dada y también admite el encadenamiento:

["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
// "a-b-V-W-X-Y-Z-c-d"

MANIFESTACIÓN: http://jsfiddle.net/UPphH/

  • ¿Hay una forma compacta de hacer que esta versión también combine una matriz cuando encuentre una en los argumentos?

    – Nolo

    30 de marzo de 2013 a las 23:56

  • no entiendo el primer resultado ["b", "X", "Y", "Z", "c"]. ¿Por qué no es "d" ¿incluido? Me parece que si pones 6 como segundo parámetro de slice() y hay 6 elementos en la matriz a partir del índice especificado, entonces debería obtener los 6 elementos en el valor de retorno. (El doctor dice howMany para ese parámetro). desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – Alexis Wilke

    12 de diciembre de 2014 a las 2:03


  • En realidad, si uso un índice de 3 o más, no obtengo nada en la salida (caso 1., FireFox) ["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3); => [ ]

    – Alexis Wilke

    12 de diciembre de 2014 a las 2:08

  • @AlexisWilke En el primer ejemplo que usé slice método y no splice, al que te refieres en el comentario. Segundo parámetro de slice (llamado end) es índice de base cero en el que finalizar la extracción. slice extractos hasta pero sin incluir end. Por lo tanto, después insert tienes ["a", "b", "X", "Y", "Z", "c", "d"]a partir del cual slice extrae elementos con índices de 1 hasta 6es decir, de "b" a "d" pero sin incluir "d". ¿Tiene sentido?

    – Visión

    12 de diciembre de 2014 a las 8:46


  • Por alguna razón, cuando voy a usar insert2, obtengo una excepción de “Argumento esperado 1, pero obtuve 2”.

    – Corne

    26 de junio de 2020 a las 3:08

Usando Array.prototype.splice() es una forma sencilla de lograrlo

const numbers = ['one', 'two', 'four', 'five']
numbers.splice(2, 0, 'three');

console.log(numbers)

Leer más sobre matriz.prototipo.empalme

  • ¿Hay una forma compacta de hacer que esta versión también combine una matriz cuando encuentre una en los argumentos?

    – Nolo

    30 de marzo de 2013 a las 23:56

  • no entiendo el primer resultado ["b", "X", "Y", "Z", "c"]. ¿Por qué no es "d" ¿incluido? Me parece que si pones 6 como segundo parámetro de slice() y hay 6 elementos en la matriz a partir del índice especificado, entonces debería obtener los 6 elementos en el valor de retorno. (El doctor dice howMany para ese parámetro). desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – Alexis Wilke

    12 de diciembre de 2014 a las 2:03


  • En realidad, si uso un índice de 3 o más, no obtengo nada en la salida (caso 1., FireFox) ["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3); => [ ]

    – Alexis Wilke

    12 de diciembre de 2014 a las 2:08

  • @AlexisWilke En el primer ejemplo que usé slice método y no splice, al que te refieres en el comentario. Segundo parámetro de slice (llamado end) es índice de base cero en el que finalizar la extracción. slice extractos hasta pero sin incluir end. Por lo tanto, después insert tienes ["a", "b", "X", "Y", "Z", "c", "d"]a partir del cual slice extrae elementos con índices de 1 hasta 6es decir, de "b" a "d" pero sin incluir "d". ¿Tiene sentido?

    – Visión

    12 de diciembre de 2014 a las 8:46


  • Por alguna razón, cuando voy a usar insert2, obtengo una excepción de “Argumento esperado 1, pero obtuve 2”.

    – Corne

    26 de junio de 2020 a las 3:08

Avatar de usuario de Yashwardhan Pauranik
Yashwardhan Pauranik

Si desea insertar varios elementos en una matriz a la vez, consulte esta respuesta de desbordamiento de pila: una mejor manera de empalmar una matriz en una matriz en javascript

También aquí hay algunas funciones para ilustrar ambos ejemplos:

function insertAt(array, index) {
    var arrayToInsert = Array.prototype.splice.apply(arguments, [2]);
    return insertArrayAt(array, index, arrayToInsert);
}

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

Finalmente aquí hay un jsFiddle para que puedas verlo por ti mismo: http://jsfiddle.net/luisperezphd/Wc8aS/

Y así es como usas las funciones:

// if you want to insert specific values whether constants or variables:
insertAt(arr, 1, "x", "y", "z");

// OR if you have an array:
var arrToInsert = ["x", "y", "z"];
insertArrayAt(arr, 1, arrToInsert);

  • ¿No sería mejor que insertAt() llame a insertArrayAt() una vez que haya creado un arrayToInsert de un solo elemento? Eso evita la repetición de código idéntico.

    – Matt Sach

    10 de septiembre de 2012 a las 16:12

  • este es un gran ejemplo de cuándo usar ‘aplicar’

    – CRice

    29 de enero de 2015 a las 0:44

  • Agregué un parámetro removeCount a este método para aprovechar la capacidad de splice de eliminar también elementos en ese índice: Array.prototype.splice.apply(array, [index, removeCount || 0].concat(arrayToInsert));

    – CRice

    29 de enero de 2015 a las 0:56

  • Muchas gracias y lo uso en qml

    – Se sentó

    1 de agosto de 2022 a las 15:03

¿Ha sido útil esta solución?