我创建了一个类"属性"。每个类对象都有一个名称,一个数据类型和一个布尔值(可以为空或无)。所有对象都保存到ListBuffer中。
我尝试从列表中创建一个模式,并将每个值传递给StructField()。启动工作但遗憾的是,没有其他项目被添加到架构中。
def create_schema_from_attr_list(attr_list: ListBuffer[Attribute]): StructType = {
// Get first list item and initiate schema
var schema = StructType(StructField(attr_list(0).name, attr_list(0).data_type, attr_list(0).nullable) :: Nil)
// Add remaining items
for (i <- 1 until attr_list.length) {
schema.add(attr_list(i).name, attr_list(i).data_type, attr_list(i).nullable)
println("Test " + attr_list(i).name.toString())
}
return schema
}
答案 0 :(得分:5)
add
方法不会修改schema
。认为它有点像Java中的字符串连接方法。
只需将添加结果重新分配给schema
本身,就可以使代码按照您的意愿运行:
def create_schema_from_attr_list(attr_list: ListBuffer[Attribute]): StructType = {
// Get first list item and initiate schema
var schema = StructType(StructField(attr_list(0).name, attr_list(0).data_type, attr_list(0).nullable) :: Nil)
// Add remaining items
for (i <- 1 until attr_list.length) {
schema = schema.add(attr_list(i).name, attr_list(i).data_type, _list(i).nullable) // here
println("Test " + attr_list(i).name.toString())
}
return schema
}
另一个解决方案,可能更简单,就是只处理ListBuffer
中的项目,从每个属性中生成StructField
,并将结果直接传递给StructType
构造函数(接受ListBuffer
的父类Seq
作为参数)。
def attributeToStructField(attr: Attribute): StructField =
StructField(attr.name, attr.data_type, attr.nullable)
def attributesToSchema(attrs: ListBuffer[Attribute]): StructType =
StructType(attrs.map(attributeToStructField))
如果您不熟悉map
函数:它已在所有集合中定义,并使用函数A => B
将ListBuffer[A]
变为ListBuffer[B]
(或任何其他集合)收集,就此而言)。您将在Scala和Spark中遇到这种高阶函数。
答案 1 :(得分:2)
您发起了schema
,但您从未在循环内将已添加的structfield
分配回schema
。这就是为什么添加的structFields
未反映在已启动的schema
中。
您应该使用DataTypes
api灵活创建schema
。以下是我的建议。希望它有所帮助
def create_schema_from_attr_list(attr_list: ListBuffer[Attribute]): StructType = {
// create bufferedlist of structfield
val bufferFields : util.ArrayList[StructField] = new util.ArrayList[StructField]
// Add structfields
for (i <- 0 until attr_list.length) {
bufferFields.add(DataTypes.createStructField(attr_list(i).name, attr_list(i).data_type, attr_list(i).nullable))
}
DataTypes.createStructType(bufferFields)
}