Ich habe ein Javascript-Array, das ich in zwei Teile aufteilen möchte, je nachdem, ob eine für jedes Element aufgerufene Funktion true
oder zurückgibt false
. Im Wesentlichen ist dies ein array.filter
, aber ich möchte auch die Elemente zur Hand haben, die herausgefiltert wurden .
Derzeit ist mein Plan, array.forEach
die Prädikatfunktion für jedes Element zu verwenden und aufzurufen. Je nachdem, ob dies wahr oder falsch ist, werde ich das aktuelle Element auf eines der beiden neuen Arrays verschieben. Gibt es einen eleganteren oder anderweitig besseren Weg, dies zu tun? Und array.filter
wo wird das Element zum Beispiel auf ein anderes Array verschoben, bevor es zurückkehrt false
?
javascript
Mike Chen
quelle
quelle
.filter
aber solche Nebenwirkungen sind schwer zu verfolgen und zu verstehen. Durchlaufen Sie einfach das Array und wechseln Sie zu dem einen oder anderen Array.Antworten:
Mit ES6 können Sie die Spread-Syntax mit redu verwenden:
Oder in einer einzigen Zeile:
quelle
Sie können lodash.partition verwenden
oder ramda.partition
quelle
Sie können dafür reduzieren:
Aktualisieren. Mit der ES6-Syntax können Sie dies auch mithilfe der Rekursion tun:
quelle
[...left, current]
oder[...right, current]
- für jedes Element. Ich kenne die genauen Interna nicht, aber ich bin sicher, dass die Konstruktion teurer ist, als einfach ein Element auf ein Array zu übertragen. Außerdem ist die Rekursion in der Regel teurer als die Iteration , da jedes Mal ein "Stapelrahmen" erstellt wird.Das klingt Rubys
Enumerable#partition
Methode sehr ähnlich .Wenn die Funktion keine Nebenwirkungen haben kann (dh das ursprüngliche Array kann nicht geändert werden), gibt es keine effizientere Möglichkeit, das Array zu partitionieren, als über jedes Element zu iterieren und das Element in eines Ihrer beiden Arrays zu verschieben.
Array
Davon abgesehen ist es wohl "eleganter", eine Methode zur Ausführung dieser Funktion zu erstellen . In diesem Beispiel wird die Filterfunktion im Kontext des ursprünglichen Arrays ausgeführt (dh istthis
das ursprüngliche Array) und empfängt das Element und den Index des Elements als Argumente (ähnlich dereach
Methode von jQuery ):quelle
Ich habe mir diesen kleinen Kerl ausgedacht. Es verwendet für alles, was Sie beschrieben haben, aber es sieht meiner Meinung nach sauber und prägnant aus.
quelle
for
Trotzdem fand ich es deutlich langsamer als eine einfache Schleife, wie in einer alten Antwort von @qwertymk. Zum Beispiel war ein Array mit 100.000 Elementen auf meinem System doppelt so langsam.In der Filterfunktion können Sie Ihre falschen Elemente in eine andere Variable außerhalb der Funktion verschieben:
Natürlich
value === false
muss ein echter Vergleich sein;)Aber es macht fast die gleiche Operation wie
forEach
. Ich denke, Sie solltenforEach
für eine bessere Lesbarkeit des Codes verwenden.quelle
Versuche dies:
DEMO
quelle
Was ist damit?
Wahrscheinlich ist dies effizienter als der Spread-Operator
Oder etwas kürzer, aber hässlicher
quelle
Einfach zu lesen.
quelle
Am Ende habe ich das gemacht, weil es leicht zu verstehen ist (und vollständig mit Typoskript getippt ist).
quelle