¿Cómo puedo agregar nuevos elementos de matriz al comienzo de una matriz en Javascript?

1587

Tengo la necesidad de agregar o anteponer elementos al comienzo de una matriz.

Por ejemplo, si mi matriz se ve a continuación:

[23, 45, 12, 67]

Y la respuesta de mi llamada AJAX es 34, quiero que la matriz actualizada sea como la siguiente:

[34, 23, 45, 12, 67]

Actualmente estoy planeando hacerlo así:

var newArray = [];
newArray.push(response);

for (var i = 0; i < theArray.length; i++) {
    newArray.push(theArray[i]);
}

theArray = newArray;
delete newArray;

¿Hay alguna forma mejor de hacer esto? ¿Tiene Javascript alguna funcionalidad incorporada que haga esto?

La complejidad de mi método es O(n)y sería realmente interesante ver mejores implementaciones.

Luna
fuente
99
FYI: Si necesita insertar continuamente un elemento al comienzo de una matriz, es más rápido usar pushdeclaraciones seguidas de una llamada a reverse, en lugar de llamar unshifttodo el tiempo.
Jenny O'Reilly
2
@ JennyO'Reilly deberías publicar esto como respuesta. Coincidió perfectamente con mi caso de uso. gracias
robar
2
Pruebas de rendimiento: jsperf.com/adding-element-to-the-array-start Pero los resultados son diferentes para cada navegador.
Avernikoz

Respuestas:

2815

Uso unshift. Es como push, excepto que agrega elementos al principio de la matriz en lugar del final.

  • unshift/ push- agrega un elemento al principio / final de una matriz
  • shift/ pop - eliminar y devolver el primer / último elemento de una matriz

Un diagrama simple ...

   unshift -> array <- push
   shift   <- array -> pop

y gráfico:

          add  remove  start  end
   push    X                   X
    pop           X            X
unshift    X             X
  shift           X      X

Consulte la documentación de la matriz MDN . Prácticamente todos los lenguajes que tienen la capacidad de insertar / extraer elementos de una matriz también tendrán la capacidad de quitar / cambiar elementos (a veces llamados push_front/ pop_front), nunca debería tener que implementarlos usted mismo.


Como se señaló en los comentarios, si desea evitar la mutación de su matriz original, puede usar concat, que concatena dos o más matrices juntas. Puede usar esto para empujar funcionalmente un solo elemento en la parte frontal o posterior de una matriz existente; para hacerlo, debe convertir el nuevo elemento en una sola matriz de elementos:

const array = [ 3, 2, 1 ]

const newFirstElement = 4

const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ]

concatTambién puede agregar elementos. Los argumentos concatpueden ser de cualquier tipo; están implícitamente envueltos en una matriz de un solo elemento, si aún no son una matriz:

const array = [ 3, 2, 1 ]

const newLastElement  = 0

// Both of these lines are equivalent:
const newArray1 = array.concat(newLastElement)   // [ 3, 2, 1, 0 ]
const newArray2 = array.concat([newLastElement]) // [ 3, 2, 1, 0 ]
meagar
fuente
52
El uso concatpuede ser preferible ya que devuelve la nueva matriz. Muy útil para encadenar. [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)etc ... Si lo usas unshift, no puedes encadenarlo porque todo lo que obtienes es la longitud.
StJohn3D
44
shift / unshift, push / pop, empalme. Nombres muy lógicos para tales métodos.
linuxunil
1398

imagen de operaciones de matriz

var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]

Maksym
fuente
117
La razón por la cual las personas necesitan una guía visual para 4 funciones de uso cotidiano se debe a los nombres de las funciones cifradas ... ¿Por qué unshift no se llama Insertar? El turno debe ser Eliminar. etc ...
Pascal
76
// ¿Por qué unshift no se llama Insertar? // Proviene de las convenciones del lenguaje de programación C donde los elementos de la matriz se tratan como una pila. (ver perlmonks.org/?node_id=613129 para una explicación completa)
dreftymac
25
@Pascal No, insertar y eliminar serían nombres particularmente malos para esto; implican acceso aleatorio, en lugar de agregar / eliminar desde el frente de la matriz
meagar
25
Pensé que unshift debería eliminar la primera clave, y shift se insertaría en la primera clave, pero ese es solo mi pensamiento general
Shannon Hochkins,
27
Me gusta la referencia de ADN
Hunter WebDev
235

Con ES6, use el operador de propagación ...:

MANIFESTACIÓN

var arr = [23, 45, 12, 67];
arr = [34, ...arr]; // RESULT : [34,23, 45, 12, 67]

console.log(arr)

Abdennour TOUMI
fuente
19
también crea una nueva matriz, útil para funciones puras
devonj
¿Cuál es la implicación de rendimiento aquí? ¿Es más lento que usar unshift ()?
Peter T.
1
Claro, será más lento ya que es una matriz inmutable (creando una nueva matriz). Si está trabajando con una gran variedad o el rendimiento es su primer requisito, considere usarlo concaten su lugar.
Abdennour TOUMI
el rendimiento no es importante en 2018, las nuevas versiones en el navegador y el nodo obtienen el mismo rendimiento
stackdave
75

Otra forma de hacerlo a través de concat

var arr = [1, 2, 3, 4, 5, 6, 7];
console.log([0].concat(arr));

La diferencia entre concaty unshiftes que concatdevuelve una nueva matriz. El rendimiento entre ellos se puede encontrar aquí .

function fn_unshift() {
  arr.unshift(0);
  return arr;
}

function fn_concat_init() {
  return [0].concat(arr)
}

Aquí está el resultado de la prueba.

ingrese la descripción de la imagen aquí

zangw
fuente
Sería bueno para su respuesta agregar la comparación de rendimiento de ambos, además de agregar la referencia.
Ivan De Paz Centeno
Acabo de recibir jsPerf no está disponible temporalmente mientras estamos trabajando en el lanzamiento de v2. Por favor intente más tarde desde el enlace. Otra buena razón para incluir los resultados en lugar de vincularlos.
Tigger
Resultado jsPref :: 25,510unshift ± 3.18% 99% más lento concat: 2,436,894 ± 3.39% más rápido
Iluminador el
En el último Safari, fn_unshift () se ejecuta más rápido.
passatgt
En el último Safari (v 10), fn_unshift () es más lento nuevamente.
rmcsharry
45

Hoja de trucos rápida:

Los términos shift / unshift y push / pop pueden ser un poco confusos, al menos para las personas que pueden no estar familiarizadas con la programación en C.

Si no está familiarizado con la jerga, aquí hay una traducción rápida de términos alternativos, que puede ser más fácil de recordar:

* array_unshift()  -  (aka Prepend ;; InsertBefore ;; InsertAtBegin )     
* array_shift()    -  (aka UnPrepend ;; RemoveBefore  ;; RemoveFromBegin )

* array_push()     -  (aka Append ;; InsertAfter   ;; InsertAtEnd )     
* array_pop()      -  (aka UnAppend ;; RemoveAfter   ;; RemoveFromEnd ) 
dreftymac
fuente
20

tienes una matriz: var arr = [23, 45, 12, 67];

Para agregar un elemento al principio, desea usar splice:

var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);

ozimax06
fuente
arr.splice (0, arr.length, 34);
Lior Elrom
1
@LiorElrom, ¿qué hace tu fragmento?
Janus Troelsen
@poushy es específico del navegador, en Firefox 54 es un unshift50% más rápido (pero en su mayoría más legible)
icl7126
@poushy Ya no. Mucho más lento.
Andrew
17

Sin mutar

En realidad, todos unshift/ pushy shift/ pop mutan la matriz de origen.

El unshift/ pushagregar un elemento a la matriz existente desde el inicio / final y shift/ popeliminar un elemento desde el principio / final de una matriz.

Pero hay pocas formas de agregar elementos a una matriz sin una mutación. el resultado es una nueva matriz, para agregar al final de la matriz use el siguiente código:

const originArray = ['one', 'two', 'three'];
const newItem = 4;

const newArray = originArray.concat(newItem); // ES5
const newArray2 = [...originArray, newItem]; // ES6+

Para agregar al comienzo de la matriz original, use el siguiente código:

const originArray = ['one', 'two', 'three'];
const newItem = 0;

const newArray = (originArray.slice().reverse().concat(newItem)).reverse(); // ES5
const newArray2 = [newItem, ...originArray]; // ES6+

Con la forma anterior, agrega al principio / final de una matriz sin una mutación.

AmerllicA
fuente
Acabo de poner una slicefunción al final de originArraypara evitar su mutabilidad.
Ahmad Khani
1
¡Increíble! Cuando se trata de la gestión del Estado (Redux) ... ¡esta respuesta es preciosa!
Pedro Ferreira
1
Esta es la forma correcta!
mmm
10

Uso de la desestructuración de ES6: (evitando la mutación de la matriz original)

const newArr = [item, ...oldArr]

Ben Adam
fuente
8

Si necesita insertar continuamente un elemento al comienzo de una matriz, es más rápido usar pushsentencias seguidas de una llamada a reverse, en lugar de llamar aunshift todo el tiempo.

Prueba de referencia: http://jsben.ch/kLIYf

Jenny O'Reilly
fuente
1
Nota: la matriz inicial debe estar vacía.
192kb
5

Usando splice, insertamos un elemento en una matriz al comienzo:

arrName.splice( 0, 0, 'newName1' );
Srikrushna
fuente
Es una respuesta correcta. Gracias Srikrushna
Khanh Tran