我正在编写适用于数值的Spark RDD的通用数学运算函数。
对于乘法,我有一些看起来像这样的东西:
def mult(rdd1: RDD[AnyVal], rdd2: RDD[AnyVal]): RDD[AnyVal] = {
rdd1.zip(rdd2).map(row => row._1 * row._2)
}
*
不是AnyVal的成员,所以这不会编译。我能做些什么来使这项工作?
答案 0 :(得分:2)
如何将<TR>
用于数字类型?
这应该有效:
Numeric
如果你想能够将任何东西与任何东西相乘,那么你需要告诉编译器如何做到这一点。
为此,让我们声明一个描述功能的特征:
def mult[X:Numeric](rdd1: RDD[X], rdd2: RDD[X]): RDD[X] = {
import Numeric.Implicits._
rdd1.zip(rdd2).map(row => row._1 * row._2)
}
现在你可以定义一个泛型函数乘法,将乘法提升到其他类型(我将使用trait Multiplier[A, B, C] {
def multiply(a: A, b: B): C
}
你可以使用Seq
):
RDD
现在让我们告诉编译器如何将def multiply[A,B,C](as:Seq[A],bs:Seq[B])(implicit multiplier: Multiplier[A,B,C]): Seq[C] =
as zip bs map ( p => multiplier.multiply(p._1, p._2))
与Int
相乘(Scala可以将String
与String
相乘,而不是另一个Int
因此,让我们定义乘数:
implicit object IntStringMultipler extends Multiplier[Int, String, Seq[String]] {
override def multiply(a: Int, b: String): Seq[String] = (1 to a) map (_ => b)
}
为了让它更有趣,2 * "x"
将Seq("x", "x")
而不是"xx"
,就像Scala自己的"x" * 2
一样。
现在我们可以致电multiply(Seq(2, 3), Seq("a", "b"))
来获取List(Vector("a", "a"), Vector("b", "b", "b"))