元组上的模式匹配

jav*_*dba 2 scala tuples pattern-matching

对于下面的条件 - 已经为a定义了模式匹配 Tuple2(BigDecimal,BigDecimal)

  (r.get(0), r.get(1)) match {
    case (r0: BigDecimal, r1: BigDecimal) => (bigDecimalNullToZero(r0), bigDecimalNullToZero(r1))
    case (r0,r1)  => {
      error(s"Unable to compare [$r0] and [$r1]"); (0L,0L)
    }
  }
Run Code Online (Sandbox Code Playgroud)

为什么比赛没被认出?

在此输入图像描述

在此输入图像描述

Tza*_*har 6

我将假设r在这种情况下是类型org.apache.spark.sql.Row- 如果是这种情况,你只是使用错误的BigDecimal类 - 你匹配Scala的内置scala.math.BigDecimal而Spark java.math.BigDecimal在引擎盖下使用.

所以 - 如果你使用Java的类匹配,这应该按预期工作:

(r.get(0), r.get(1)) match {
  case (r0: java.math.BigDecimal, r1: java.math.BigDecimal) => (bigDecimalNullToZero(r0), bigDecimalNullToZero(r1))
  case (r0,r1)  => {
    error(s"Unable to compare [$r0] and [$r1]"); (0L,0L)
  }
}
Run Code Online (Sandbox Code Playgroud)

我用这个完整的例子来测试这个:

import spark.implicits._

val df = Seq(
  (BigDecimal(2.1), BigDecimal(2.3)) // using Scala's BigDecimal to build DF
).toDF("name", "hit_songs")

df.foreach { r: Row => (r.get(0), r.get(1)) match {
  case (s1: BigDecimal, s2: BigDecimal) => println("found Scala BigDecimals")
  case (s1: java.math.BigDecimal, s2: java.math.BigDecimal) => println("found Java BigDecimals")
  case (s1, s2) => println(s"Not found")
}}

// prints: found Java BigDecimals
Run Code Online (Sandbox Code Playgroud)

PS你通常可以使用Row的unapply函数从一行中简化这种"提取" ,即匹配Row(a, b, ...):

df.map {
  case Row(s1: java.math.BigDecimal, s2: java.math.BigDecimal, _*) => (s1, s2)
}
Run Code Online (Sandbox Code Playgroud)