Ich habe zwei Arrays. Das erste Array enthält einige Werte, während das zweite Array Indizes der Werte enthält, die aus dem ersten Array entfernt werden sollen. Beispielsweise:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
Ich möchte die an Indizes vorhandenen Werte 0,2,4
aus entfernen valuesArr
. Ich dachte, die native splice
Methode könnte helfen, also kam ich auf Folgendes:
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
Aber es hat nicht funktioniert, weil nach jedem splice
die Indizes der Werte in valuesArr
unterschiedlich waren. Ich könnte dieses Problem lösen, indem ich ein temporäres Array verwende und alle Werte in das zweite Array kopiere, aber ich habe mich gefragt, ob es native Methoden gibt, an die wir mehrere Indizes übergeben können, um Werte aus einem Array zu entfernen.
Ich würde eine jQuery-Lösung bevorzugen. (Nicht sicher, ob ich grep
hier verwenden kann)
quelle
$.each(rvm.reverse(), function(e, i ) {})
removeValFromIndex
in aufsteigender Reihenfolge sortiert istHier ist eine, die ich benutze, wenn ich nicht mit lodash / Unterstrich gehe:
quelle
slice
, die zu entfernenden Indizes neu berechnen müssten (-1 einIndexestoBeRemoved
), aber es funktioniert tatsächlich!IndexesToBeRemoved
Array nach aufsteigend sortiert ist.IndexesToBeRemoved
sortiert (aufsteigend).Nicht
in-place
aber kann mitgrep
undinArray
Funktionen von gemacht werdenjQuery
.Überprüfen Sie diese Geige.
quelle
valuesArr = $.grep(...);
Ich schlage vor, Sie verwenden Array.prototype.filter
quelle
Die MDN-Referenz finden Sie hier
quelle
In reinem JS können Sie das Array rückwärts durchlaufen, um die
splice()
Indizes der Elemente in der nächsten Schleife nicht durcheinander zu bringen:quelle
Es fühlt sich notwendig an, eine Antwort mit der
O(n)
Zeit zu posten :). Das Problem bei der Spleißlösung besteht darin, dass jeder Aufruf einige Zeit in Anspruch nimmt, da die zugrunde liegende Implementierung des Arrays buchstäblich ein Array ist . Dies ist am ausgeprägtesten, wenn wir ein Beispiel einrichten, um dieses Verhalten auszunutzen:splice
O(n)
Dies entfernt Elemente von der Mitte bis zum Start, daher zwingt jedes Entfernen die js-Engine,
n/2
Elemente zu kopieren . Wir haben(n/2)^2
insgesamt Kopieroperationen , die quadratisch sind.Die Spleißlösung (vorausgesetzt, sie
is
ist bereits in absteigender Reihenfolge sortiert, um Gemeinkosten zu beseitigen) sieht folgendermaßen aus:Es ist jedoch nicht schwer, eine lineare Zeitlösung zu implementieren, indem das Array von Grund auf neu erstellt wird und eine Maske verwendet wird, um festzustellen, ob wir Elemente kopieren oder nicht (sort wird dies verschieben
O(n)log(n)
). Das Folgende ist eine solche Implementierung (nicht, dass siemask
aus Geschwindigkeitsgründen boolesch invertiert ist):Ich habe dies auf jsperf.com ausgeführt und selbst
n=100
die Spleißmethode ist um 90% langsamer. Für größere wirdn
dieser Unterschied viel größer sein.quelle
Eine einfache und effiziente Lösung (lineare Komplexität) mit Filter und Set :
Der große Vorteil dieser Implementierung besteht darin, dass die Set-Lookup-Operation (
has
Funktion) eine konstante Zeit benötigt und beispielsweise schneller als die Antwort von nevace ist.quelle
Quick ES6 One Liner:
quelle
removeValFromIndex
a erstellenSet()
undremoveValFromIndex.has
stattdessen verwendenincludes
.Dies funktioniert gut für mich und funktioniert auch beim Löschen aus einem Array von Objekten:
Es gibt möglicherweise eine kürzere und effizientere Möglichkeit, dies zu schreiben, aber dies funktioniert.
quelle
Eine einfache Lösung mit ES5. Dies scheint heutzutage für die meisten Anwendungen angemessener zu sein, da sich viele nicht mehr auf jQuery usw. verlassen möchten.
Wenn die zu entfernenden Indizes in aufsteigender Reihenfolge sortiert sind:
Wenn die zu entfernenden Indizes nicht sortiert sind:
quelle
Sie können durch das Ersetzen Sie den Code korrigieren
removeValFromIndex
mitremoveValFromIndex.reverse()
. Wenn nicht garantiert wird, dass dieses Array aufsteigende Reihenfolge verwendet, können Sie stattdessen verwendenremoveValFromIndex.sort(function(a, b) { return b - a })
.quelle
removeValFromIndex
in aufsteigender Reihenfolge sind.Hier ist eine Möglichkeit:
Beispiel auf jsFiddle
MDN auf Array.prototype.reduceRight
quelle
Wenn Sie underscore.js verwenden , können Sie damit
_.filter()
Ihr Problem lösen.Wenn Sie versuchen, Elemente mithilfe einer Liste von Elementen anstelle von Indizes zu entfernen, können Sie außerdem einfach Folgendes verwenden
_.without()
:Jetzt
filteredArr
sollte es sein["V2", "V4", "V5"]
quelle
filter + indexOf (IE9 +):
Oder mit ES6 Filter + Find (Edge +):
quelle
Hier ist ein Quickie.
quelle
Klingt so, als ob Übernehmen genau das sein könnte, wonach Sie suchen.
Vielleicht würde so etwas funktionieren?
quelle
.splice()
Methode erwartet jedoch keine Liste der zu entfernenden Elemente, sondern einen einzelnen Index des Elements, bei dem mit dem Entfernen begonnen werden soll, gefolgt von der Anzahl der zu entfernenden Elemente ...Für mehrere Artikel oder Einzelartikel:
Ich schlage vor, Sie verwenden Array.prototype.filter
Verwenden Sie indexOf niemals, wenn Sie den Index bereits kennen!:
Machen:
mit Hashes ... mit Array.prototype.map
quelle
Das funktioniert. Sie würden dabei jedoch ein neues Array erstellen. Ich bin mir nicht sicher, ob Sie das wollen oder nicht, aber technisch gesehen wäre es ein Array, das nur die gewünschten Werte enthält.
quelle
Sie können versuchen, dies zu verwenden.
delete array[index]
Dadurch wird das Element nicht vollständig entfernt, sondern der Wert auf festgelegtundefined
.quelle
Sie können ein
Set
Array aus dem Array erstellen und dann ein Array aus dem Set erstellen.quelle