2016-12-12 4 views
0

Ich bin neugierig, wie die Elemente eines Arrays in Klasse für Klasse zu filtern.Scala flatMap Filterelemente in Array-Instanz des Typs

case class FooBarGG(foo: Int, bar: String, baz: Option[String]) 
val df = Seq((1, "first", "A"), (1, "second", "A"), 
    (2, "noValidFormat", "B"), 
    (1, "lastAssumingSameDate", "C")) 
    .toDF("foo", "bar", "baz") 
    .as[FooBarGG] 
    .drop("replace") 

    val labelEncoder = multiLabelIndexer(columnsFactor) 
    val pipe = new Pipeline().setStages(labelEncoder) 
    val fitted = pipe.fit(df) 

    def multiLabelIndexer(factorCols: Seq[String]): Array[StringIndexer] = { 
    factorCols.map(
     cName => new StringIndexer() 
     .setInputCol(cName) 
     .setOutputCol(s"${cName}_index") 
    ) 
    .toArray 
    } 

konnte nicht erhalten flatMap zu arbeiten, wie ein Transformer und nicht StringIndexerModel erwartet wird.

stages flatMap { 
    //  case _.isInstanceOf[StringIndexerModel] => Some(_)//Some(_.asInstanceOf[StringIndexerModel]) 
    case StringIndexerModel => Some(_) 
    case _ => None 
    } 

Mein Ansatz basiert auf Filtering a Scala List by type

Antwort

3

Verwendung sammeln

Collect sehr viel klarer und eleganter ist

stages collect { case a: StringIndexerModel => a } 

Bei collect Sie brauchen nicht Some und None Werten zurückzukehren, wählen Sie stattdessen nur die, die Sie brauchen, und ignorieren Sie die anderen Fälle, das ist der Grund, warum das Sammeln eleganter ist.

Auch isInstanceOf ist redundant und ausführlich, wenn die Mustererkennung verwendet wird, da die Mustererkennung verwendet werden kann, um äußere Typen zu ermitteln.

Zum Beispiel

val list = List(1, 2, 3) 

list match { 
    case a: List => //no need to use isInstanceOf 
    case _ => 
} 

Hinweis können wir nur den Typ als Liste herauszufinden, aber kann nicht herausfinden Liste [Int] wegen der Typ Löschung

0

einen benannten Parameter verwenden und jede Art ist nicht die Lösung entsprechen.

case c: StringIndexerModel => Some(c) 
case _ => None