Как насчет использования 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
с String
(Scala может умножать 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"))
Ну, если вы действительно уверены, что вы будете получать числовой тип и не может быть строка, то вы можете явно привести его '.asInstanceOf [NumericalTypeYouNeed]' , Излишне говорить, что это не рекомендуется, так как оно будет взорвано во время выполнения, если что-то еще придет, и я бы поставил под вопрос, почему «rdd1» и «rdd2'' AnyVal в первую очередь. –
@AkosKrivachy Я использовал AnyVal, потому что RDD содержат числовые значения. Есть ли лучший способ получить эту функциональность? –
Имеет ли 'rdd1' и' rdd2' один и тот же числовой тип? –