我最终需要从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-loop
。For 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中的语句和表达式