Ist es immer leistungsfähiger, withFilter anstelle von filter zu verwenden, wenn anschließend Funktionen wie Map, Flatmap usw. angewendet werden?
Warum werden nur Map, Flatmap und Foreach unterstützt? (Erwartete Funktionen wie forall / existieren ebenfalls)
Antworten:
Aus den Scala-Dokumenten :
So
filter
wird die ursprüngliche Sammlung nehmen und eine neue Kollektion produzieren, aberwithFilter
wird nicht streng (dh träge) passiert ungefilterten Werte bis hin zum späterenmap
/flatMap
/withFilter
Anrufen, einen zweiten Durchlauf durch die (gefilterte) Sammlung speichern. Daher ist es effizienter, wenn diese nachfolgenden Methodenaufrufe weitergeleitet werden.In der Tat
withFilter
ist speziell für die Arbeit mit Ketten dieser Methoden konzipiert, in die ein zum Verständnis entzuckert wird. Hierfür sind keine anderen Methoden (wieforall
/exists
) erforderlich, daher wurden sie nicht zumFilterMonadic
Rückgabetyp von hinzugefügtwithFilter
.quelle
view
Sie diese Option, wenn Karten / Filter faul sein sollen.view
undwithFilter
? Warum wird die Ansicht nicht verwendetfor-loops
?Don’t create temporary collections
im verknüpften Bereich suchen .withFilter
Martin Odersky selbst nutzt es ausdrücklich in seinen Scala Kursen auf Coursera, die sehr empfehle ich. Wenn er dies tut, kann dies auch anderen Trost geben, obwohl der Unterschied normalerweise nur 1 Zeichen beträgt. Zum Beispielseq.view filter p
vs.seq withFilter p
.Neben der hervorragenden Antwort von Shadowlands möchte ich ein intuitives Beispiel für den Unterschied zwischen
filter
und gebenwithFilter
.Betrachten wir den folgenden Code
Die meisten Menschen erwarten
result
, gleich zu seinList(1)
. Dies ist seit Scala 2.8 der Fall, weil das Verständnis in übersetzt wirdWie Sie sehen können, wandelt die Übersetzung die Bedingung in einen Aufruf von um
withFilter
. Vor Scala 2.8 wurde das Verständnis in Folgendes übersetzt:Mit wäre
filter
der Wert vonresult
ziemlich unterschiedlich :List(1, 2, 3)
. Die Tatsache, dass wir dasgo
Flag erstellen,false
hat keine Auswirkung auf den Filter, da der Filter bereits fertig ist. Auch in Scala 2.8 wird dieses Problem mit gelöstwithFilter
. BeiwithFilter
Verwendung wird die Bedingung jedes Mal ausgewertet, wenn auf ein Element innerhalb einermap
Methode zugegriffen wird.Referenz : - S.120, Scala in Aktion (Cover Scala 2.10), Manning Publications, Milanjan Raychaudhuri - Oderskys Gedanken zur Übersetzung zum Verständnis
quelle
Der Hauptgrund, weil forall / exist nicht implementiert ist, ist, dass der Anwendungsfall folgender ist:
Um forall / exist zu implementieren, müssen wir alle Elemente erhalten und die Faulheit verlieren.
Also zum Beispiel:
Beachten Sie, dass ten_rand_even_naturals immer noch ein Iterator ist. Nur wenn wir toList aufrufen, werden die Zufallszahlen in der Kette generiert und gefiltert
Beachten Sie, dass map (Identität) äquivalent zu map (i => i) ist und hier verwendet wird, um ein withFilter-Objekt wieder in den ursprünglichen Typ zu konvertieren (z. B. eine Sammlung, ein Stream, ein Iterator).
quelle
Für den forall / existierenden Teil:
wäre das gleiche wie (obwohl ein wenig unintuitiv)
In ähnlicher Weise kann .filter (). Exists () zu einer exist () -Prüfung kombiniert werden.
quelle
Die Verwendung für den Ertrag kann eine Problemumgehung sein, zum Beispiel:
quelle
Um dieses Problem zu umgehen, können Sie andere Funktionen nur mit
map
und implementierenflatMap
.Darüber hinaus ist diese Optimierung bei kleinen Sammlungen nutzlos…
quelle