【问题标题】:Scala Ordinal Method Call AliasingScala序数方法调用别名
【发布时间】:2015-03-18 14:54:05
【问题描述】:

在 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
}

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

【问题讨论】:

    标签: scala functional-programming apache-spark implicit


    【解决方案1】:

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

    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)
    }
    

    【讨论】:

      【解决方案2】:

      另一种选择是将Row 转换为特定领域的案例类,恕我直言,这会导致代码更具可读性:

      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)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-25
        • 2018-06-26
        • 2018-10-08
        • 1970-01-01
        • 2016-03-25
        • 2014-07-11
        • 2011-02-01
        • 2013-05-16
        相关资源
        最近更新 更多