Scala - 在模式匹配表达式中扩展参数列表

时间:2015-07-18 00:10:10

标签: scala apache-spark pattern-matching

我是Scala的新手,并尝试将其用作Spark的界面。我遇到了将通用CSV转换为DataFrame函数的问题。例如,我有一个包含大约50个字段的CSV,其中第一个是tasknameid。我可以得到以下工作:

val reader = new CSVReader(new StringReader(txt))

reader.readAll().map(_ match {
  case Array(task, name, id, _*) => Row(task, name, id)
  case unexpectedArrayForm =>
    throw new RuntimeException("Record did not have correct number of fields: "+ unexpectedArrayForm.mkString(","))
})

但是,我宁愿不必硬编码创建spark Row所需的字段数。我试过这个:

val reader = new CSVReader(new StringReader(txt))

reader.readAll().map(_ match {
  case Array(args @ _*) => Row(args)
  case unexpectedArrayForm =>
    throw new RuntimeException("Record did not have correct number of fields: "+ unexpectedArrayForm.mkString(","))
})

但它只是创建一个带有单个元素的Row对象。如何让它展开args中的Row(args),这样如果我有一个N个元素的数组,我会得到一个包含N个元素的行?

2 个答案:

答案 0 :(得分:4)

通过添加_*

将输入更改为可变长度
Row(args:_*)

This is what Row accepts per its apply signature

事实上,你甚至不需要做任何事情,除了将它传递给Row,因为它已经是正确的序列类型。

reader.readAll().map(Row(_:_*))

答案 1 :(得分:3)

这应该可以解决问题:

val reader = new CSVReader(new StringReader(txt))

reader.readAll().map(_ match {
  case a: Array[String] => Row(a:_*)
  case unexpectedArrayForm =>
    throw new RuntimeException("Record did not have correct number of fields: "+ unexpectedArrayForm.mkString(","))
})

编辑以正确省略数组类型