J'ai deux tableaux. Le premier tableau contient des valeurs tandis que le second tableau contient des indices des valeurs qui doivent être supprimées du premier tableau. Par exemple:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
Je souhaite supprimer les valeurs présentes dans les indices 0,2,4
de valuesArr
. J'ai pensé que la splice
méthode native pourrait aider, alors j'ai proposé:
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
Mais cela n'a pas fonctionné car après chaque splice
, les indices des valeurs valuesArr
étaient différents. Je pourrais résoudre ce problème en utilisant un tableau temporaire et en copiant toutes les valeurs dans le deuxième tableau, mais je me demandais s'il existe des méthodes natives auxquelles nous pouvons transmettre plusieurs indices auxquels supprimer des valeurs d'un tableau.
Je préférerais une solution jQuery. (Je ne sais pas si je peux utiliser grep
ici)
$.each(rvm.reverse(), function(e, i ) {})
removeValFromIndex
est trié par ordre croissantEn voici un que j'utilise lorsque je ne vais pas avec lodash / underscore:
la source
slice
vous devrez recalculer les index à supprimer (-1 activéIndexestoBeRemoved
), mais cela fonctionne réellement!IndexesToBeRemoved
tableau est trié par ordre croissant.IndexesToBeRemoved
est trié (croissant).Non,
in-place
mais peut être fait en utilisantgrep
et lesinArray
fonctions dejQuery
.vérifiez ce violon.
la source
valuesArr = $.grep(...);
Je vous suggère d'utiliser Array.prototype.filter
la source
La référence MDN est ici
la source
En JS pur, vous pouvez faire une boucle à travers le tableau à l'envers, donc
splice()
ne gâcherez pas les indices des éléments suivants dans la boucle:la source
Il se sent nécessaire de poster une réponse avec le
O(n)
temps :). Le problème avec la solution d'épissure est qu'en raison de l'implémentation sous-jacente de array étant littéralement un tableau , chaquesplice
appel prendra duO(n)
temps. Ceci est plus prononcé lorsque nous configurons un exemple pour exploiter ce comportement:Cela supprime les éléments du milieu au début, donc chaque suppression oblige le moteur js à copier des
n/2
éléments, nous avons des(n/2)^2
opérations de copie au total qui est quadratique.La solution d'épissure (en supposant qu'elle
is
est déjà triée par ordre décroissant pour se débarrasser des frais généraux) se présente comme suit:Cependant, il n'est pas difficile d'implémenter une solution de temps linéaire, en reconstruisant le tableau à partir de zéro, en utilisant un masque pour voir si nous copions des éléments ou non (le tri le poussera à
O(n)log(n)
). Ce qui suit est une telle implémentation (pas quimask
est booléen inversé pour la vitesse):J'ai couru ceci sur jsperf.com et même
n=100
la méthode d'épissure est 90% plus lente. Pour les plus grands,n
cette différence sera beaucoup plus grande.la source
Doublure Quick ES6 one:
la source
removeValFromIndex
unSet()
et utilisez auremoveValFromIndex.has
lieu deincludes
.Une solution simple et efficace (complexité linéaire) utilisant le filtre et l' ensemble :
Le grand avantage de cette implémentation est que l'opération (
has
fonction) de recherche Set prend un temps constant, étant plus rapide que la réponse de nevace, par exemple.la source
Cela fonctionne bien pour moi et fonctionne également lors de la suppression d'un tableau d'objets:
Il peut y avoir une manière plus courte et plus efficace d'écrire ceci, mais cela fonctionne.
la source
Une solution simple utilisant ES5. Cela semble plus approprié pour la plupart des applications de nos jours, car beaucoup ne veulent plus s'appuyer sur jQuery, etc.
Lorsque les index à supprimer sont triés par ordre croissant:
Lorsque les index à supprimer ne sont pas triés:
la source
Vous pouvez corriger votre code en le remplaçant
removeValFromIndex
parremoveValFromIndex.reverse()
. S'il n'est pas garanti que ce tableau utilise l'ordre croissant, vous pouvez utiliser à la placeremoveValFromIndex.sort(function(a, b) { return b - a })
.la source
removeValFromIndex
sont dans l'ordre croissant.Voici une possibilité:
Exemple sur jsFiddle
MDN sur Array.prototype.reduceRight
la source
Si vous utilisez underscore.js , vous pouvez utiliser
_.filter()
pour résoudre votre problème.De plus, si vous essayez de supprimer des éléments en utilisant une liste d'éléments au lieu d'index, vous pouvez simplement utiliser
_.without()
, comme ceci:Maintenant
filteredArr
devrait être["V2", "V4", "V5"]
la source
filtre + indexOf (IE9 +):
Ou avec filtre ES6 + find (Edge +):
la source
Voici un quickie.
la source
On dirait que Apply pourrait être ce que vous recherchez.
peut-être que quelque chose comme ça fonctionnerait?
la source
.splice()
méthode ne s'attend pas à une liste d'éléments à supprimer, elle attend un seul index de l'élément auquel commencer la suppression suivi du nombre d'éléments à supprimer ...Pour plusieurs articles ou article unique:
Je vous suggère d'utiliser Array.prototype.filter
N'utilisez jamais indexOf si vous connaissez déjà l'index!:
Faire:
avec Hashes ... en utilisant Array.prototype.map
la source
Cela marche. Cependant, vous créeriez un nouveau tableau dans le processus. Je ne sais pas si c'est ce que vous voulez ou non, mais techniquement, ce serait un tableau contenant uniquement les valeurs souhaitées.
la source
Vous pouvez essayer d'utiliser
delete array[index]
Cela ne supprimera pas complètement l'élément mais définira plutôt la valeur surundefined
.la source
Vous pouvez construire un à
Set
partir du tableau, puis créer un tableau à partir de l'ensemble.la source