Filterung eine Scala-Liste nach Typ
Habe ich eine Klasse Struktur wie diese
abstract class A
class B extends A
class C extends A
class D extends A
class E extends A
und ich habe eine Sammlung von verschiedenen Instanzen, zum Beispiel:
val xs = List(new D, new B, new E, new E, new C, new B)
Meine Frage ist, gibt es einen eleganten Weg heraus zu filtern einige der Unterklassen aus der Liste?
Sagen wir, ich möchte alle Instanzen außer B 's und C' s. Ich kann es mit einer Reihe von isInstanceOf ist, oder mit sammeln wie diese:
val ys = (xs collect {
case b: B => None
case c: C => None
case notBorC => notBorC
}).filter(_ != None).asInstanceOf[List[A]]
Funktioniert es, aber es fühlt sich unbehaglich, vor allem, weil der filter und gegossen. Gibt es eine elegantere Möglichkeit? Weniger code ist bevorzugt, und ich möchte eine Lösung haben, die nicht aktualisiert werden müssen, wenn ich mehr Unterklassen von A.
Du musst angemeldet sein, um einen Kommentar abzugeben.
flatMap
shit! (wie Sie sagen):In Ihrem Fall, Sie waren immer ein
List[ScalaObject]
weilScalaObject
ist die kleinste Obere Schranke vonNone
,D
, undE
.option2iterable
passiert, die Umwandlung derSome
/None
Werte iterables. Eine alternative Möglichkeit, dies zu schreiben, nicht entstehen, weil Sie die implizite Konvertierung verwendencollect
gefolgt vonflatten
stattflatMap
. Super Antwort, Travis!collect
können verwendet werden zum filtern von Werten, auf denen die Funktion definiert ist:Bekommen, alle Werte des Typs A:
Bekommen, alle Werte mit Ausnahme von B und C:
Formulierung der Probleme als Fragen scheint eine ziemlich gute Möglichkeit, Sie zu lösen 🙂 Meine Frage ist eigentlich die Antwort - nur filtern nach Untertyp:
ys
ist die leere Liste, wenn Ihre Ausschluss-Listen enthältclassOf[A]
, dann müssen Sie etwas anders. Zum Beispiel:xs.filterNot(x => List(classOf[A]).exists(y => y.isInstance(x)))
. Travis' Lösung weist diese Eigenschaft als gut.