Ich möchte ein Array von Elementen mithilfe der map()
Funktion filtern . Hier ist ein Code-Snippet:
var filteredItems = items.map(function(item)
{
if( ...some condition... )
{
return item;
}
});
Das Problem ist, dass herausgefilterte Elemente immer noch Speicherplatz im Array belegen und ich sie vollständig löschen möchte.
Irgendeine Idee?
EDIT: Danke, ich habe vergessen filter()
, was ich wollte, ist eigentlich ein filter()
dann ein map()
.
EDIT2: Vielen Dank für den Hinweis map()
und filter()
sind nicht in allen Browsern implementiert, obwohl mein spezifischer Code nicht für die Ausführung in einem Browser vorgesehen war.
javascript
functional-programming
data-manipulation
client-side
Vincent Robert
quelle
quelle
Antworten:
Sie sollten die
filter
Methode anstelle der Zuordnung verwenden, es sei denn, Sie möchten die Elemente im Array zusätzlich zur Filterung mutieren.z.B.
[Bearbeiten: Natürlich können Sie immer
sourceArray.filter(...).map(...)
sowohl filtern als auch mutieren]quelle
map
mutiert nichtmap
.x=[1,2,3];y = x.map(z => z*2);console.log(x,y);
Inspiriert von dieser Antwort, erweiterte ich später einen Blog-Beitrag, in dem ich dies ausführlich durchführte. Ich empfehle, dies zu überprüfen, wenn Sie ein tieferes Verständnis dafür entwickeln möchten, wie Sie über dieses Problem nachdenken können. Ich versuche, es Stück für Stück zu erklären und am Ende einen JSperf-Vergleich zu geben, bei dem die Geschwindigkeitsüberlegungen berücksichtigt werden.
Das heißt, das tl; dr ist folgendes: Um das zu erreichen, was Sie verlangen (Filtern und Zuordnen innerhalb eines Funktionsaufrufs), würden Sie verwenden
Array.reduce()
.Allerdings ist die besser lesbar und (weniger wichtig) in der Regel deutlich schneller 2 Ansatz ist es , nur die Verwendung Filter und Karte miteinander verkettet:
[1,2,3].filter(num => num > 2).map(num => num * 2)
Im Folgenden wird beschrieben, wie dies
Array.reduce()
funktioniert und wie Filter und Zuordnung in einer Iteration durchgeführt werden können. Wenn dies zu kurz ist, empfehle ich dringend, den oben verlinkten Blog-Beitrag zu lesen, der ein viel freundlicheres Intro mit klaren Beispielen und Fortschritten darstellt.Sie geben ein Argument reduzieren, das eine (normalerweise anonyme) Funktion ist.
Diese anonyme Funktion akzeptiert zwei Parameter - einer (wie die an map / filter / forEach übergebenen anonymen Funktionen) ist der Iterat, der bearbeitet werden soll. Es gibt ein weiteres Argument für die übergebene anonyme Funktion, um zu reduzieren, dass diese Funktionen nicht akzeptiert werden. Dies ist der Wert, der zwischen Funktionsaufrufen weitergegeben wird, der häufig als Memo bezeichnet wird .
Beachten Sie, dass Array.filter () nur ein Argument (eine Funktion) akzeptiert, Array.reduce () jedoch auch ein wichtiges (wenn auch optionales) zweites Argument: einen Anfangswert für 'memo', der als dessen an diese anonyme Funktion übergeben wird erstes Argument und kann anschließend mutiert und zwischen Funktionsaufrufen weitergegeben werden. (Wenn es nicht angegeben wird, ist 'memo' im ersten anonymen Funktionsaufruf standardmäßig der erste Iteratee, und das Argument 'iteratee' ist tatsächlich der zweite Wert im Array.)
In unserem Fall übergeben wir zunächst ein leeres Array und wählen dann basierend auf unserer Funktion aus, ob unser Iteratee in unser Array eingefügt werden soll oder nicht - dies ist der Filterprozess.
Schließlich geben wir bei jedem anonymen Funktionsaufruf unser 'Array in Bearbeitung' zurück, und Reduce nimmt diesen Rückgabewert und übergibt ihn als Argument (Memo genannt) an den nächsten Funktionsaufruf.
Auf diese Weise können Filter und Map in einer Iteration ausgeführt werden, wodurch sich die Anzahl der erforderlichen Iterationen halbiert. Bei jeder Iteration wird jedoch nur doppelt so viel Arbeit geleistet, sodass nur Funktionsaufrufe gespeichert werden, die in Javascript nicht so teuer sind .
Eine ausführlichere Erklärung finden Sie in den MDN- Dokumenten (oder in meinem Beitrag, auf den am Anfang dieser Antwort verwiesen wird).
Grundlegendes Beispiel für einen Anruf zum Reduzieren:
prägnantere Version:
Beachten Sie, dass der erste Iterat nicht größer als eins war und daher gefiltert wurde. Beachten Sie auch das initialMemo, das nur benannt wurde, um seine Existenz zu verdeutlichen und die Aufmerksamkeit darauf zu lenken. Erneut wird es als 'Memo' an den ersten anonymen Funktionsaufruf übergeben, und dann wird der zurückgegebene Wert der anonymen Funktion als 'Memo'-Argument an die nächste Funktion übergeben.
Ein weiteres Beispiel für den klassischen Anwendungsfall für Memos wäre die Rückgabe der kleinsten oder größten Zahl in einem Array. Beispiel:
Ein Beispiel für das Schreiben einer eigenen Reduktionsfunktion (dies hilft mir oft, solche Funktionen zu verstehen):
Die eigentliche Implementierung ermöglicht beispielsweise den Zugriff auf Dinge wie den Index, aber ich hoffe, dies hilft Ihnen dabei, ein unkompliziertes Gefühl für das Wesentliche zu bekommen.
quelle
reduce
ist, dass dem Rückruf im Gegensatz zufilter
+ einmap
Indexargument übergeben werden kann, das der Index des ursprünglichen Arrays und nicht der des gefilterten ist.Das macht die Karte nicht. Sie wollen wirklich Array.filter . Oder wenn Sie die Elemente wirklich aus der ursprünglichen Liste entfernen möchten, müssen Sie dies unbedingt mit einer for-Schleife tun.
quelle
Array- Filter-Methode
quelle
var arr = [1,2,"xxx", "yyy"]; arr = arr.filter(function(e){ return e!="xxx" }) console.log(arr)
Sie müssen jedoch beachten, dass das
Array.filter
nicht in allen Browsern unterstützt wird, daher müssen Sie Prototypen erstellen:Auf diese Weise können Sie jede Methode prototypisieren, die Sie benötigen.
quelle
Die folgende Anweisung bereinigt das Objekt mithilfe der Kartenfunktion.
quelle
Ich habe gerade eine Array-Schnittmenge geschrieben, die auch Duplikate korrekt behandelt
https://gist.github.com/gkucmierz/8ee04544fa842411f7553ef66ac2fcf0
quelle
Zuerst können Sie die Karte verwenden und mit der Verkettung können Sie den Filter verwenden
quelle