Comment puis-je ajouter de nouveaux éléments de tableau au début d'un tableau en Javascript?

1587

J'ai besoin d'ajouter ou d'ajouter des éléments au début d'un tableau.

Par exemple, si mon tableau ressemble à ci-dessous:

[23, 45, 12, 67]

Et la réponse de mon appel AJAX est 34, je veux que le tableau mis à jour soit comme suit:

[34, 23, 45, 12, 67]

Actuellement, je prévois de le faire comme ceci:

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

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

theArray = newArray;
delete newArray;

Y a-t-il une meilleure façon de procéder? Javascript a-t-il une fonctionnalité intégrée qui le fait?

La complexité de ma méthode est O(n)et il serait vraiment intéressant de voir de meilleures implémentations.

Lune
la source
9
Pour info: si vous devez insérer en continu un élément au début d'un tableau, il est plus rapide d'utiliser des pushinstructions suivies d'un appel à reverse, au lieu d'appeler unshifttout le temps.
Jenny O'Reilly
2
@ JennyO'Reilly, vous devez poster ceci comme réponse. Correspondait parfaitement à mon cas d'utilisation. merci
voler
2
Tests de performances: jsperf.com/adding-element-to-the-array-start Mais les résultats sont différents pour chaque navigateur.
Avernikoz

Réponses:

2815

Utilisez unshift. C'est comme push, sauf qu'il ajoute des éléments au début du tableau au lieu de la fin.

  • unshift/ push- ajoute un élément au début / fin d'un tableau
  • shift/ pop - supprime et retourne le premier / dernier élément d'un tableau

Un schéma simple ...

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

et graphique:

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

Consultez la documentation de la baie MDN . Pratiquement tous les langages qui ont la capacité de pousser / pop des éléments d'un tableau auront également la possibilité de décaler / déplacer (parfois appelés push_front/ pop_front) des éléments, vous ne devriez jamais avoir à les implémenter vous-même.


Comme indiqué dans les commentaires, si vous souhaitez éviter de muter votre tableau d'origine, vous pouvez utiliser concat, qui concatène deux tableaux ou plus ensemble. Vous pouvez l'utiliser pour pousser fonctionnellement un seul élément à l'avant ou à l'arrière d'un tableau existant; pour ce faire, vous devez transformer le nouvel élément en un seul tableau d'éléments:

const array = [ 3, 2, 1 ]

const newFirstElement = 4

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

concatpeut également ajouter des éléments. Les arguments de concatpeuvent être de tout type; ils sont implicitement enveloppés dans un tableau à un seul élément, s'ils ne sont pas déjà un tableau:

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
la source
52
L'utilisation concatpeut être préférable car elle renvoie le nouveau tableau. Très utile pour enchaîner. [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)etc ... Si vous utilisez unshift, vous ne pouvez pas faire ce chaînage car tout ce que vous récupérez est la longueur.
StJohn3D
4
shift / unshift, push / pop, épissure. Noms très logiques pour de telles méthodes.
linuxunil
1398

image des opérations de tableau

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

Maksym
la source
117
La raison pour laquelle les gens ont besoin d'un guide visuel pour 4 fonctions utilisées au quotidien est à cause des noms de fonction cryptés ... Pourquoi unshift n'est-il pas appelé Insert? Shift doit être Remove. etc ...
Pascal
76
// Pourquoi unshift n'est pas appelé Insert? // Il vient des conventions du langage de programmation C où les éléments du tableau étaient traités comme une pile. (voir perlmonks.org/?node_id=613129 pour une explication complète)
dreftymac
25
@Pascal Non, insérer et supprimer serait particulièrement mauvais pour cela; ils impliquent un accès aléatoire, au lieu d'ajouter / supprimer de l'avant de la baie
meagar
25
J'aurais pensé que le décalage devrait supprimer la première clé, et le décalage serait inséré à la première clé, mais c'est juste ma pensée générale
Shannon Hochkins
27
J'aime la référence ADN
Hunter WebDev
235

Avec ES6, utilisez l'opérateur d'étalement ...:

DEMO

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

console.log(arr)

Abdennour TOUMI
la source
19
crée également un nouveau tableau, utile pour les fonctions pures
devonj
quelle est l'implication des performances ici? Est-ce plus lent que d'utiliser unshift ()?
Peter T.
1
Bien sûr, il sera plus lent car il s'agit d'un tableau immuable (création d'un nouveau tableau). Si vous travaillez avec une grande baie ou si les performances sont votre première exigence, pensez à les utiliser à la concatplace.
Abdennour TOUMI
les performances ne sont pas importantes en 2018, les nouvelles versions du navigateur et du nœud obtiennent les mêmes performances
stackdave
75

Une autre façon de le faire grâce à concat

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

La différence entre concatet unshiftest que concatrenvoie un nouveau tableau. La performance entre eux peut être trouvée ici .

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

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

Voici le résultat du test

entrez la description de l'image ici

zangw
la source
Il serait bon que votre réponse ajoute la comparaison des performances des deux en plus d'ajouter la référence.
Ivan De Paz Centeno
Je viens de recevoir jsPerf est temporairement indisponible pendant que nous travaillons sur la sortie de la v2. Veuillez réessayer plus tard à partir du lien. Une autre bonne raison d'inclure les résultats au lieu de les lier.
Tigger
Résultat jsPrefunshift :: 25 510 ± 3,18% 99% plus lent concat: 2 436 894 ± 3,39% le plus rapide
Illuminateur
Dans le dernier Safari, fn_unshift () s'exécute plus rapidement.
passatgt
Dans le dernier Safari (v 10), fn_unshift () est à nouveau plus lent.
rmcsharry
45

Cheatsheet rapide:

Les termes shift / unshift et push / pop peuvent être un peu déroutants, du moins pour les personnes qui ne sont pas familières avec la programmation en C.

Si vous n'êtes pas familier avec le jargon, voici une traduction rapide de termes alternatifs, qui peuvent être plus faciles à retenir:

* 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
la source
20

vous avez un tableau: var arr = [23, 45, 12, 67];

Pour ajouter un élément au début, vous souhaitez utiliser splice:

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

ozimax06
la source
arr.splice (0, arr.length, 34);
Lior Elrom
1
@LiorElrom que fait votre extrait?
Janus Troelsen
@poushy c'est spécifique au navigateur, dans Firefox 54 est unshift50% plus rapide (mais surtout plus lisible)
icl7126
@poushy Plus maintenant. Beaucoup plus lent.
Andrew
17

Sans mutate

En fait, tout unshift/ pushet shift/ pop mute le tableau d'origine.

Le unshift/ pushajouter un élément au tableau existant de début / fin et shift/ popsupprimer un élément du début / fin d'un tableau.

Mais il existe peu de façons d'ajouter des éléments à un tableau sans mutation. le résultat est un nouveau tableau, à ajouter à la fin du tableau, utilisez le code ci-dessous:

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

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

Pour ajouter au début du tableau d'origine, utilisez le code ci-dessous:

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

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

Avec la méthode ci-dessus, vous ajoutez au début / à la fin d'un tableau sans mutation.

AmerllicA
la source
Je viens de mettre une slicefonction à la fin de l' originArrayempêcher de mutabilité.
Ahmad Khani
1
Impressionnant! En ce qui concerne la gestion de l'État (Redux) ... cette réponse est précieuse!
Pedro Ferreira
1
C'est la bonne façon!
mmm
10

Utilisation de la déstructuration ES6: (en évitant la mutation hors du tableau d'origine)

const newArr = [item, ...oldArr]

Ben Adam
la source
8

Si vous devez insérer un élément en continu au début d'un tableau, il est plus rapide d'utiliser des pushinstructions suivies d'un appel à reverse, au lieu d'appeler unshifttout le temps.

Test de référence: http://jsben.ch/kLIYf

Jenny O'Reilly
la source
1
Remarque: le tableau initial doit être vide.
192kb
5

En utilisant splicenous insérons un élément dans un tableau au début:

arrName.splice( 0, 0, 'newName1' );
Srikrushna
la source
C'est une bonne réponse. Merci Srikrushna
Khanh Tran