Scala-如何使用StructField名称列表过滤StructType?

时间:2019-08-12 22:13:32

标签: scala apache-spark pattern-matching

我正在编写一种解析模式的方法,并希望使用列名列表过滤结果StructType。这是原始架构的StructField名称的子集。

因此,如果标记为isFilteringReq = true,我想以相同的顺序返回一个StructType,它仅包含带有specialColumnNames中名称的StructFields。如果该标志为false,则返回原始的StructType。

val specialColumnNames = Seq("metric_1", "metric_2", "metric_3")

首先,我得到一个具有模式匹配的原始模式。

val customSchema: StructType = schemaType match {
  case "type_1" => getType1chema()
  case "type_2" => getType2chema()
}

有两个问题:

1 -大括号之后,我无法直接将.filter()应用于customSchema。并得到一个Cannot resolve symbol filter。所以我写了一个单独的方法makeCustomSchema。但是我不需要单独的对象。在这种情况下,是否有更优雅的方法来应用过滤?

2 -我可以过滤originalStruct,但只能使用一个硬编码的列名。我应该如何将specialColumnNames传递给contains()?

def makeCustomSchema(originalStruct: StructType, isFilteringReq: Boolean, updColumns: Seq[String]) = if (isFilteringReq) {
  originalStruct.filter(s => s.name.contains("metric_1"))
} else {
  originalStruct
}

val newSchema = makeCustomSchema(customSchema, isFilteringReq, specialColumnNames)

1 个答案:

答案 0 :(得分:1)

通过mag而不是传递Seq,您可以过滤字段是否在集合中。 另外,我不会使用标志,而是可以在没有过滤条件时传递空的Set或使用Set。 无论如何,您还可以使用case类免费提供的copy方法。 这样的事情应该起作用。

Option[Set[String]]

通常,您不需要构建这样的结构,是否尝试过在DataFrame / DataSet中使用def makeCustomSchema(originalStruct: StructType, updColumns:Set[String]): StructType = { updColumns match { case s if s.isEmpty => originalStruct case _ => originalStruct.copy( fields = originalStruct.fields.filter( f => updColumns.contains(f.name))) } } 方法?