scala, filter, eine Sammlung basiert auf mehreren Voraussetzungen
Ich habe einen code wie:
val strs = List("hello", "andorra", "trab", "world")
def f1(s: String) = !s.startsWith("a")
def f2(s: String) = !s.endsWith("b")
val result = strs.filter(f1).filter(f2)
nun f1 und f2 angewendet werden soll, beruht auf einem Umstand, wie zum Beispiel:
val tmp1 = if (cond1) strs.filter(f1) else strs
val out = if (cond2) tmp1.filter(f2) else tmp1
ist es ein schöner Weg, dies zu tun, ohne eine zwischenvariable mit einem tmp1
?
eine Möglichkeit zu filtern, basierend auf einer Liste von Funktionen, wie:
val fs = List(f1 _,f2 _)
fs.foldLeft(strs)((fn, list) => list.filter(fn))
aber dann würde ich brauchen, um zu bauen eine Liste von Funktionen auf der Grundlage der Bedingungen (und ja, ich würde sich das problem mit einem temporären string-Liste variable, um eine temporäre Funktion list-variable (oder sollte ich brauchen, um eine veränderliche Liste)).
Ich Suche so etwas (natürlich nicht kompilieren, sonst hätte ich bereits die Antwort auf die Frage):
val result =
strs
.if(cond1, filter(f1))
.if(cond2, filter(f2))
- Klingt wie Sie wollen, die eine Liste von Tupeln (Zustand,filterPredicate). Anschließend können Sie diese Liste filtern basierend auf, ob oder nicht der Zustand (z.B. _._1) hält. Jetzt haben Sie eine Liste von Funktionen, die Sie anwenden möchten. Sie können dann diese Karte mit dem string und reduzieren Sie mit && (Logik und). Sorry, wenn es zu wellig ist.
- danke, das ist eine gute Idee, auch, aber ich suchte etwas, das mehr wie noah ' s Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Konnte Sie problemlos verwenden Sie eine implizite Klasse geben Sie diese syntax:
Ich würde verwendet haben
if
wie der name der Methode, aber es ist ein reserviertes Wort.Sie können dies tun, durch die Summe Ihrer Prädikat-Funktionen.
Beobachten, dass ein filterprädikat
A => Boolean
hat eine append-operation:Und ein identity-Wert:
erfüllt die Bedingung, dass für jedes Prädikat
p: A => Boolean
,append(p, id) === p
.Dadurch vereinfacht sich das problem von einschließlich/ausschließlich ein Prädikat, das auf Grundlage einer Bedingung: wenn die Bedingung false ist, schließen Sie einfach das
id
Prädikat. Es hat keine Auswirkung auf den filter, weil es gibt immertrue
.Um die Summe der Prädikate:
Beachten Sie, dass wir Falten auf
id
, so dass, wennps
leer ist, bekommen wir die Identität Prädikat, d.h. ein filter, der nichts tut, als Sie erwarten würden.Alles zusammen:
Beachten Sie, dass die Liste
strs
wurde nur einmal Durchlaufen.Nun, für die Scalaz-version der oben genannten:
filter
einmal. Fürn
Prädikate, die akzeptierten Lösung führenfilter
bis zun
mal!append
und Identitätid
Operationen/Funktionen, die vorhanden sind, oder einfach nur, dass Sie definiert werden können? Ich kann Sie nicht finden in Scala 2.10.@Noah ' s Antwort ist gut, und Sie können es nehmen und verallgemeinern es weiter, wenn Sie wollen in der Lage sein, um irgendeine Art von Aktion, die auf einer Liste gibt eine neue Liste, die einer Bedingung, wenn Sie die folgende änderung:
Dann verwenden Sie es wie diese:
Wäre es wohl eher einfach so, dass es nur den Zustand in Ihrem block für den filter, etwa so:
wobei das Ergebnis wäre ein filter angewendet wird, wenn die Bedingung erfüllt ist, oder einfach wieder die gleiche Liste.
strs filter { x => (!cond1 || f1(x)) && (!cond2 || f2(x)) }
so müssen Sie nur einmal Durchlaufen