在Spark流程中我有一个RDD[Try[(A, B)]]
。我必须使用函数RDD
转换此f: B => List[C]
。我想要获得的是RDD[Try[(A, B, C)]
,其中我必须flatMap
从函数f
的应用程序中获取的列表。
我试过这个:
val tryRdd = // Obtain the RDD[Try[(A, B)]]
val transformedRdd =
tryRdd.map {
pair =>
for {
(a, b) <- pair
c <- f(b)
} yield {
(a, b, c)
}
}
不幸的是,我得到的是RDD[Try[Nothing]]
。为什么?任何人都可以帮我理解我错在哪里吗?
我认为这个问题与RDD
并不真正相关。带有RDD
的Probabily List
将以相同的结果结束。
答案 0 :(得分:2)
for-comprehension被翻译为
pair.flatMap { case (a, b) => f(b).map { case c => (a, b, c) } }
但是f(b).map(...)
会为List[(A, B, C)]
的参数提供Try[(A, B, C)]
,而不是pair.flatMap
。所以代码根本不应该编译(除非你在范围内有一个奇怪的隐式转换)。
但是如果你使用的是IntelliJ,它可能无法显示错误并显示错误的类型(或者相反,它可能会显示工作代码中的错误):您需要实际构建项目才能看到真正的错误。
答案 1 :(得分:0)
您是否尝试过正式输入您的RDD?
val transformedRdd : RDD[Try[Tuple3]] = ...
编辑:
如果这确实引起了错误,那么地图的输出是错误的。
pair
变量的类型是Try。
由于scala不会为您执行此操作,因此您必须添加一些指令以与其内容(元组(A,B))进行交互。
另外,您不必保留Try类型。
我会使用flatMap来保持成功并清理我的RDD。
像
val transformedRdd = tryRdd.flatMap {value =>
value match {
case Success((a,b)) => ...
}
}
观看http://www.scala-lang.org/api/2.9.3/scala/util/Try.html以获取有关Try类的更多信息。