从数据帧创建结构字段列表



我最终需要从CSV构建一个模式。我可以将CSV读取到数据框架中,并且我已经定义了一个案例类。

case class metadata_class (colname:String,datatype:String,length:Option[Int],precision:Option[int])
val foo = spark.read.format("csv").option("delimiter",",").option("header","true").schema(Encoders.product[metadata_class.schema).load("/path/to/file").as[metadata_file].toDF()

现在,我正在尝试遍历该数据帧,并构建一个StructFields列表。我目前的努力:

val sList: List[StructField] = List(
for (m <- foo.as[metadata_class].collect) {
StructField[m.colname,getType(m.datatype))
})

这给了我一个类型不匹配:

found  : Unit
required: org.apache.spark.sql.types.StructField
for (m <- foo.as[metadata_class].collect) {
^

我在这里做错了什么?或者我还差一点?

在scala中通常不使用for-loopFor loop具有Unit返回类型,在您的代码中,sList的结果值将为List[Unit]:

val sList: List[Unit] = List(
for (m <- foo.as[metadata_class].collect) {
StructField(m.colname, getType(m.datatype))
}
)

但是您将sList声明为List[StructField],这就是编译错误的原因。

我想您应该使用map函数而不是for loop来迭代metadata_class对象,并从中创建StructFields

val structFields: List[StructField] = foo.as[metadata_class]
.collect
.map(m => StructField(m.colname, getType(m.datatype)))
.toList

您将通过这种方式获得List[StructField]

在scala语言中,每条语句都是返回类型为for-loop的表达式,它的返回类型是Unit

阅读更多关于语句/表达式的信息:

scala中的
  • 语句与表达式
  • scala中的语句和表达式

最新更新