Scala序数方法调用别名

时间:2015-01-20 11:32:13

标签: scala functional-programming apache-spark implicit

在Spark SQL中,我们有Row个对象,其中包含组成一行的记录列表(想想Seq[Any])。 Row有序数访问者,例如.getInt(0)getString(2)

假设序号0 = ID且序数1 =名称。很难记住顺序是什么,使代码混乱。

比如说我有以下代码

def doStuff(row: Row) = {
  //extract some items from the row into a tuple;
  (row.getInt(0), row.getString(1)) //tuple of ID, Name
}

问题是如何在Row对象中为这些字段创建别名?

我在想我可以创建一个带有隐式Row对象的方法;

def id(implicit row: Row) = row.getInt(0)
def name(implicit row: Row) = row.getString(1)

然后我可以将上面的内容重写为;

def doStuff(implicit row: Row) = {
  //extract some items from the row into a tuple;
  (id, name) //tuple of ID, Name
}

有更好/更整洁的方法吗?

2 个答案:

答案 0 :(得分:5)

您可以隐式地将这些访问者方法添加到行:

implicit class AppRow(r:Row) extends AnyVal {
    def id:String = r.getInt(0)
    def name:String = r.getString(1)
}

然后将其用作:

def doStuff(row: Row) = {
  val value = (row.id, row.name)
}

答案 1 :(得分:1)

另一种选择是将Row转换为特定于域的案例类,IMHO可以使代码更具可读性:

case class Employee(id: Int, name: String)

val yourRDD: SchemaRDD = ???
val employees: RDD[Employee] = yourRDD.map { row => 
  Employee(row.getInt(0), row.getString(1))
}

def doStuff(e: Employee) = {
  (e.name, e.id)
}