web-dev-qa-db-fra.com

Le moyen le plus efficace d'ajouter une valeur à un tableau

En supposant que j’ai un tableau de taille N (où N > 0), existe-t-il un moyen plus efficace d’ajouter des éléments au tableau sans nécessiter des é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;
}
223
samccone

Je ne suis pas sûr d'être plus efficace en termes de big-O, mais utiliser la méthode unshift est certainement plus concis:

var a = [1, 2, 3, 4];
a.unshift(0);
a; // => [0, 1, 2, 3, 4]

[Modifier]

Ce test jsPerf montre que unshift est nettement plus rapide dans au moins deux navigateurs, indépendamment des performances big-O différentes if, vous êtes prêt à modifier le tableau sur place. Si vous ne pouvez vraiment pas muter le tableau d'origine, vous feriez quelque chose comme l'extrait de code ci-dessous, qui ne semble pas être sensiblement plus rapide que votre solution:

a.slice().unshift(0); // Use "slice" to avoid mutating "a".

[Edit 2]

Pour être complet, la fonction suivante peut être utilisée à la place de l'exemple prependArray(...) d'OP pour tirer parti de la méthode Array unshift(...):

function prepend(value, array) {
  var newArray = array.slice();
  newArray.unshift(value);
  return newArray;
}

var x = [1, 2, 3];
var y = prepend(0, x);
y; // => [0, 1, 2, 3];
x; // => [1, 2, 3];
431
maerics

Si vous ajoutez un tableau à l'avant d'un autre, il est plus efficace d'utiliser simplement concat. Alors:

var newArray = values.concat(oldArray);

Mais ce sera toujours O(N) dans la taille de oldArray. Néanmoins, il est plus efficace que de parcourir manuellement oldArray. De plus, selon les détails, cela peut vous aider, car si vous pré-préférez de nombreuses valeurs, il est préférable de les placer d'abord dans un tableau, puis de concattre 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 de solution, faites ce que @GWW a dit et utilisez une liste chaînée ou une structure de données différente.

43
mgiuca

Avec ES6, vous pouvez maintenant utiliser l'opérateur spread pour créer un nouveau tableau avec vos nouveaux éléments insérés avant les éléments d'origine.

// Prepend a single item.
const a = [1, 2, 3];
console.log([0, ...a]);

// Prepend an array.
const a = [2, 3];
const b = [0, 1];
console.log([...b, ...a]);

Mise à jour 2018-08-17: Performance

Je voulais que cette réponse présente une syntaxe alternative que je pense être plus mémorable et concise. Il convient de noter que, selon certains points de repère (voir cette autre réponse ), cette syntaxe est nettement plus lente. Cela n’aura probablement aucune importance si vous ne réalisez pas plusieurs de ces opérations en boucle.

42
Frank Tan

Si vous souhaitez ajouter un tableau (a1 avec un tableau a2), vous pouvez utiliser:

var a1 = [1, 2];
var a2 = [3, 4];
Array.prototype.unshift.apply(a1, a2);
console.log(a1);
// => [3, 4, 1, 2]
32
uroslates

si vous devez conserver l’ancien tableau, découpez l’ancien et décochez la ou les nouvelles valeurs, au début de la tranche.

var oldA=[4,5,6];
newA=oldA.slice(0);
newA.unshift(1,2,3)

oldA+'\n'+newA

/*  returned value:
4,5,6
1,2,3,4,5,6
*/
6
kennebec

Il y a une méthode spéciale:

a.unshift(value);

Mais si vous souhaitez ajouter plusieurs éléments au tableau, il serait plus rapide d'utiliser une telle méthode:

var a = [1, 2, 3],
    b = [4, 5];

function prependArray(a, b) {
    var args = b;
    args.unshift(0);
    args.unshift(0);
    Array.prototype.splice.apply(a, args);
}

prependArray(a, b);
console.log(a); // -> [4, 5, 1, 2, 3]
3
bjornd

J'ai quelques nouveaux tests de différentes méthodes de prépayage . Pour les petits tableaux (<1000 élems), le leader est pour cycle associé à la méthode Push . Pour les grands tableaux, 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 propagation ES6 est plus de 100 fois plus lente dans tous les navigateurs.

https://jsbench.me/cgjfc79bgx/1

2
John Klimov

Exemple de prépositionnement en place:

var A = [7,8,9]
var B = [1,2,3]

A.unshift(...B)

console.log(A) // [1,2,3,7,8,9]

0
Miguel Mota

L'appel de unshift ne renvoie que la longueur du nouveau tableau. Donc, pour ajouter un élément au début et pour retourner un nouveau tableau, j'ai fait ceci:

let newVal = 'someValue';
let array = ['hello', 'world'];
[ newVal ].concat(array);

ou simplement avec l'opérateur spread:

[ newVal, ...array ]

De cette façon, le tableau d'origine reste intact.

0
rehman_00001