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

1880

Necesito agregar o anteponer elementos al comienzo de una matriz.

Por ejemplo, si mi matriz se parece a la siguiente:

[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 planeo 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? ¿Javascript tiene alguna funcionalidad incorporada que haga esto?

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

3
  • dieciséis
    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. 15 de febrero de 2018 a las 8:56
  • 2
    @ JennyO'Reilly deberías publicar esto como respuesta. Coincidía perfectamente con mi caso de uso. Gracias
    rob
    7 de junio de 2018 a las 12:19
  • 2
    Pruebas de rendimiento: jsperf.com/adding-element-to-the-array-start Pero los resultados son diferentes para cada navegador. 23/04/19 a las 18:34
3230

Utilice 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 - elimina y devuelve 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 MDN Array . Prácticamente todos los lenguajes que tienen la capacidad de empujar / extraer elementos de una matriz también tendrán la capacidad de deshacer / desplazar (a veces llamados push_front/ pop_front) elementos, 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 al frente o al dorso de una matriz existente; para hacerlo, debe convertir el nuevo elemento en una matriz de un solo elemento:

const array = [3, 2, 1]

const newFirstElement = 4

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

console.log(newArray);

concattambién puede agregar elementos. Los argumentos de 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 ]

console.log(newArray1);
console.log(newArray2);
2
  • 58
    Es concatpreferible usarlo, ya que devuelve la nueva matriz. Muy útil para encadenar. [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)etc ... Si usa unshift, no puede hacer ese encadenamiento porque todo lo que obtiene es la longitud. 23 de septiembre de 2016 a las 18:27
  • 5
    shift / unshift, push / pop, empalme. Nombres muy lógicos para tales métodos. 25/04/18 a las 12:32
1542

imagen de operaciones de matriz

var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]
7
  • 154
    La razón por la que la gente necesita una guía visual para las 4 funciones de uso diario es por los nombres de las funciones cifradas ... ¿Por qué no se llama Insertar unshift? Shift debe ser Eliminar. etc ...
    Pascal
    29/06/2013 a las 21:24
  • 88
    // ¿Por qué unshift no se llama Insert? // Viene de las convenciones del lenguaje de programación C donde los elementos de la matriz se tratan como una pila. (consulte perlmonks.org/?node_id=613129 para obtener una explicación completa) 26/07/2013 a las 21:05
  • 30
    @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 22/10/2013 a las 13:06
  • 27
    Hubiera pensado que unshift debería eliminar la primera tecla, y shift se insertaría en la primera tecla, pero ese es solo mi pensamiento general. 25 de septiembre de 2014 a las 1:50
  • 32
    Me gusta la referencia de ADN 20 de mayo de 2016 a las 0:54
277

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)
4
  • 23
    también crea una nueva matriz, útil para funciones puras
    devonj
    8 de agosto de 2017 a las 19:01
  • 1
    ¿Cuál es la implicación de rendimiento aquí? ¿Es más lento que usar unshift ()? 2 mar 2018 a las 9:49
  • 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. 2 mar. 18 a las 15:42
  • el rendimiento no es importante en 2018, las nuevas versiones en el navegador y el nodo obtienen el mismo rendimiento 16 de julio de 2018 a las 6:11
85

Otra forma de hacer eso 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. La actuación 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í

5
  • Sería bueno que su respuesta adjuntara la comparación de rendimiento de ambos además de agregar la referencia. 15 de junio de 2016 a las 9:12
  • Acabo de recibir jsPerf que no está disponible temporalmente mientras estamos trabajando en el lanzamiento de v2. Vuelva a intentarlo más tarde desde el enlace. Otra buena razón para incluir los resultados en lugar de vincularlos.
    Tigger
    21 de agosto de 2016 a las 1:00
  • Resultado de jsPref :: 25,510unshift ± 3,18% 99% más lento concat: 2,436,894 ± 3,39% más rápido 3 de noviembre de 2016 a las 10:28
  • En el último Safari, fn_unshift () se ejecuta más rápido. 21/07/2017 a las 13:22
  • En el último Safari (v 10), fn_unshift () vuelve a ser más lento. 9/11/2017 a las 11:22
49

Hoja de referencia 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 pueden ser más fáciles 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 ) 
23

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

Para agregar un elemento al principio, desea utilizar splice:

var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);
4
  • arr.splice (0, longitud de arr., 34); 15/10/15 a las 20:08
  • 1
    @LiorElrom ¿qué hace tu fragmento? 22/06/2016 a las 11:31
  • @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
    17 de mayo de 2017 a las 7:16
  • @poushy Ya no. Mucho más lento.
    Andrew
    12/09/19 a las 16:15
18

Sin mutar

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

El unshift/ pushagrega un elemento a la matriz existente desde el principio / final y shift/ popelimina un elemento desde el principio / final de una matriz.

Pero hay algunas 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.

2
  • Solo puse una slicefunción al final de originArraypara evitar la mutabilidad. 4 de diciembre de 2019 a las 7:34
  • 1
    ¡Impresionante! Cuando se trata de la gestión del estado (Redux) ... ¡esta respuesta es preciosa! 23 feb.20 a las 13:16
17

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

const newArr = [item, ...oldArr]

1
15

Hoja de referencia para anteponer nuevos elementos en la matriz

1. Array#unshift

const list = [23, 45, 12, 67];

list.unshift(34);

console.log(list); // [34, 23, 45, 12, 67];

2. Array#splice

const list = [23, 45, 12, 67];

list.splice(0, 0, 34);

console.log(list); // [34, 23, 45, 12, 67];

3. Propagación de ES6 ...

const list = [23, 45, 12, 67];
const newList = [34, ...list];

console.log(newList); // [34, 23, 45, 12, 67];

4. Array#concat

const list = [23, 45, 12, 67];
const newList = [32].concat(list);

console.log(newList); // [34, 23, 45, 12, 67];

Nota: En cada uno de estos ejemplos, puede anteponer varios elementos proporcionando más elementos para insertar.

9

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.

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

2
  • 2
    Nota: la matriz inicial debe estar vacía.
    192kb
    15/08/19 a las 10:12
  • En 2021, su punto de referencia muestra una ganancia integral para unshifttodos los principales navegadores de escritorio (al menos en esta Mac). 7 de julio a las 21:52
8

Usando spliceinsertamos un elemento en una matriz al principio:

arrName.splice( 0, 0, 'newName1' );
0
3

primero puede invertir la matriz y luego agregar elem a la matriz y luego revertirla.

const arr = [2,3,4,5,6];
const arr2 = 1;
arr.reverse();
//[6,5,4,3,2]
arr.push(arr2);

console.log(arr.reverse()); // [1,2,3,4,5,6]

buen bloqueo

ali alizadeh.

2

Si desea enviar elementos que están en una matriz al principio de su matriz, use <func>.apply(<this>, <Array of args>):

const arr = [1, 2];
arr.unshift.apply(arr, [3, 4]);
console.log(arr); // [3, 4, 1, 2]
0

Rendimiento: para arreglos pequeños, puede elegir el que desee, sin diferencias de rendimiento significativas. Pero para algunas decenas de elementos, unshift () es mucho mejor que cualquier otra cosa.

Vea los resultados aquí: https://jsben.ch/GDA3P

-1

puede revertir su matriz y empujar los datos, al final nuevamente revertirlo:

var arr=[2,3,4,5,6];
var arr2=1;
arr.reverse();
//[6,5,4,3,2]
arr.push(arr2);
1
  • No tiene sentido esta solución.
    AFetter
    27 de junio a las 23:37