En supposant que j'ai un tableau qui a une taille de N
(où N > 0
), y a-t-il un moyen plus efficace de pré-ajouter au tableau qui ne nécessiterait pas d'étapes O (N + 1)?
En code, essentiellement, ce que je fais actuellement est
function prependArray(value, oldArray) {
var newArray = new Array(value);
for(var i = 0; i < oldArray.length; ++i) {
newArray.push(oldArray[i]);
}
return newArray;
}
javascript
arrays
prepend
samccone
la source
la source
Réponses:
Je ne suis pas sûr d'être plus efficace en termes de big-O, mais l'utilisation de la
unshift
méthode est certainement plus concise:[Éditer]
Ce benchmark jsPerf montre qu'il
unshift
est décemment plus rapide dans au moins quelques navigateurs, indépendamment des performances big-O éventuellement différentes si vous êtes d'accord avec la modification du tableau en place. Si vous ne pouvez vraiment pas muter le tableau d'origine, vous feriez quelque chose comme l'extrait ci-dessous, qui ne semble pas être beaucoup plus rapide que votre solution:[Modifier 2]
Pour être complet, la fonction suivante peut être utilisée à la place de l'exemple OP
prependArray(...)
pour tirer parti de launshift(...)
méthode Array :la source
prepend
"unshift
"?unshift
semble plus approprié pour une telle opération de tableau (il déplace les éléments ... plus ou moins physiquement).prepend
serait plus approprié pour les listes liées, où vous ajoutez littéralement des éléments.push
et lesunshift
deux contiennentu
, tandis quepop
etshift
n'en ont pas.Avec ES6, vous pouvez désormais utiliser l' opérateur d'étalement pour créer un nouveau tableau avec vos nouveaux éléments insérés avant les éléments d'origine.
Mise à jour 2018-08-17: performances
Je voulais que cette réponse présente une syntaxe alternative que je pense être plus mémorable et concise. Il est à noter que selon certains benchmarks (voir cette autre réponse ), cette syntaxe est nettement plus lente. Cela n'aura probablement aucune importance, sauf si vous effectuez plusieurs de ces opérations en boucle.
la source
unshift
Si vous ajoutez un tableau à l'avant d'un autre tableau, il est plus efficace de simplement l'utiliser
concat
. Alors:Mais ce sera toujours O (N) dans la taille de oldArray. Pourtant, il est plus efficace que l'itération manuelle sur oldArray. En outre, selon les détails, cela peut vous aider, car si vous souhaitez ajouter de nombreuses valeurs, il est préférable de les placer d'abord dans un tableau, puis de concatrer oldArray à la fin, plutôt que de les ajouter individuellement.
Il n'y a aucun moyen de faire mieux que O (N) dans la taille de oldArray, car les tableaux sont stockés dans une mémoire contiguë avec le premier élément dans une position fixe. Si vous souhaitez insérer avant le premier élément, vous devez déplacer tous les autres éléments. Si vous avez besoin d'un moyen de contourner cela, faites ce que @GWW a dit et utilisez une liste chaînée ou une structure de données différente.
la source
unshift
. Mais notez que a) qui mute oldArray alorsconcat
que non (donc celui qui vous convient le mieux dépend de la situation), et b) il n'insère qu'un élément.[0]
), tandis qu'unshift le mute en place. Mais les deux devraient être O (N). Acclamations également pour le lien vers ce site - semble très pratique.Si vous souhaitez ajouter un tableau (a1 avec un tableau a2), vous pouvez utiliser ce qui suit:
la source
Si vous devez conserver l'ancien tableau, découpez l'ancien et décompressez la ou les nouvelles valeurs au début de la tranche.
la source
J'ai de nouveaux tests de différentes méthodes de pré-paiement. Pour les petits réseaux (<1000 elems), le leader est pour le cycle couplé à une méthode push. Pour les tableaux énormes, la méthode Unshift devient le leader.
Mais cette situation n'est réelle que pour le navigateur Chrome. Dans Firefox, unshift a une optimisation impressionnante et est plus rapide dans tous les cas.
La diffusion ES6 est 100 fois plus lente dans tous les navigateurs.
https://jsbench.me/cgjfc79bgx/1
la source
Il existe une méthode spéciale:
Mais si vous souhaitez ajouter plusieurs éléments au tableau, il serait plus rapide d'utiliser une telle méthode:
la source
Array.prototype.unshift.apply(a,b);
Exemple de pré-paiement sur place:
la source
L'appel
unshift
renvoie uniquement la longueur du nouveau tableau. Donc, pour ajouter un élément au début et pour retourner un nouveau tableau, j'ai fait ceci:ou simplement avec l'opérateur spread:
De cette façon, la matrice d'origine reste intacte.
la source