52

私はこのようなクラス構造を持っています

abstract class A
class B extends A
class C extends A
class D extends A
class E extends A

さまざまなインスタンスのコレクションがあります。たとえば、次のとおりです。

val xs = List(new D, new B, new E, new E, new C, new B)

私の質問は、リストからいくつかのサブクラスを除外するエレガントな方法はありますか?

B と C 以外のすべてのインスタンスが必要だとしましょう。一連の isInstanceOf を使用するか、collect を次のように使用して実行できます。

val ys = (xs collect {
    case b: B => None
    case c: C => None
    case notBorC => notBorC
}).filter(_ != None).asInstanceOf[List[A]]

これは機能しますが、主にフィルターとキャストが原因で、ぎこちなく感じます。もっとエレガントな方法はありますか?コードは少ない方が望ましいので、A のサブクラスを追加しても更新する必要がないソリューションが必要です。

4

3 に答える 3

105

collect関数が定義されている値をフィルタリングするために使用できます。

タイプ A のすべての値を取得します。

xs.collect { case a: A => a }

B と C を除くすべての値を取得します。

xs diff xs.collect { case x@(_: B | _: C) => x }
于 2015-07-10T18:39:42.077 に答える
53

flatMapそのたわごと!(彼らが言うように):

scala> val ys = xs flatMap {
     |   case _: B | _: C => None
     |   case other => Some(other)
     | }
ys: List[A] = List(D@7ecdc97b, E@2ce07e6b, E@468bb9d1)

あなたの場合、 、、およびの最小上限であるList[ScalaObject]ため、 を取得していました。ScalaObjectNoneDE

于 2012-11-14T15:44:21.330 に答える
4

問題を質問として定式化することは、それらを解決するための非常に良い方法のようです:)私の質問は実際に答えを提供します-サブタイプでフィルタリングするだけです:

val ys = xs filterNot(List(classOf[B], classOf[C]) contains _.getClass)
于 2012-11-14T15:41:14.947 に答える