将StructField添加到现有模式

br0*_*ipe 0 loops scala apache-spark apache-spark-sql

我创建了一个类"属性".每个类对象都有一个名称,一个数据类型和一个布尔值(可以为空或可以为空).所有对象都保存到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
}
Run Code Online (Sandbox Code Playgroud)

ste*_*ino 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

}
Run Code Online (Sandbox Code Playgroud)

另一个解决方案,可能更简单,就是只处理其中的项ListBufferStructField从每个属性中取出并将结果直接传递给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))
Run Code Online (Sandbox Code Playgroud)

如果你不熟悉的map功能:它定义了所有集合,并采取了功能A => B果然一ListBuffer[A]ListBuffer[B](或任何其他集合,对于这个问题).你会在Scala和Spark中遇到这种高阶函数.