Scala flatMap在Type数组实例中过滤元素

时间:2016-12-12 12:52:29

标签: scala casting apache-spark-ml

我很好奇如何按类过滤scala中数组的元素。

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
  }

无法让flatMap工作,因为Transformer而不是StringIndexerModel

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

我的方法基于Filtering a Scala List by type

2 个答案:

答案 0 :(得分:3)

使用收藏

Collect更加清晰优雅

stages collect { case a: StringIndexerModel => a }

如果collect您不需要返回SomeNone值,只需选择您需要的值而忽略其他情况这就是收集的原因更优雅。

使用模式匹配时,isInstanceOf也是冗余和冗长的,因为模式匹配可用于计算外部类型。

例如

val list = List(1, 2, 3)

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

请注意,我们只能将类型计算为List,但由于类型擦除无法找出List [Int]

答案 1 :(得分:0)

使用命名参数并且不匹配任何类型是解决方案。

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