我需要在使用Spark处理数据时计算新列。 下面的代码工作正常
scala> def f[Int](iter: Iterator[Int]) : Iterator[(Int, Int)] = {
| var res = List[(Int, Int)]()
| while (iter.hasNext)
| {
| val x = iter.next;
| res = res ::: List((x, x))
| }
| res.iterator
| }
f: [Int](iter: Iterator[Int])Iterator[(Int, Int)]
scala> sc.parallelize(Iterator(1,1,2,5,1,3).toSeq).mapPartitions(f).collect
res34: Array[(Int, Int)] = Array((1,1), (1,1), (2,2), (5,5), (1,1), (3,3))
每个元素的第二个值应该使用一些复杂的逻辑来计算,当我尝试使用变量甚至是常量时,函数的定义都会失败。
scala> def f[Int](iter: Iterator[Int]) : Iterator[(Int, Int)] = {
| var res = List[(Int, Int)]()
| var y = 1
| while (iter.hasNext)
| {
| val x = iter.next;
| res = res ::: List((x, y)) // List((x, 1))
| }
| res.iterator
| }
<console>:39: error: type mismatch;
found : List[(Int, Any)]
required: List[(Int, Int)]
res = res ::: List((x, y)) // List((x, 1))
为什么会失败以及如何解决? 感谢
答案 0 :(得分:3)
从签名中删除[Int]
。
它告诉编译器,&#34; Int&#34;在函数范围内是一个类型参数,因此它可以是任何类型--Int,String。
执行var y = 1
时,Scala会推断类型为scala.Int,但在函数Int中,如果用作类型参数,List是此类型参数的元组列表,而不是Scala.Int。
这两个将起作用:
def f[E](iter: Iterator[E]) : Iterator[(E, Int)] = {
var res = List[(E, Int)]()
var y = 1
while (iter.hasNext)
{
val x = iter.next;
res = res ::: List((x, y)) // List((x, 1))
}
res.iterator
}
和
def f(iter: Iterator[Int]) : Iterator[(Int, Int)] = {
var res = List[(Int, Int)]()
var y = 1
while (iter.hasNext)
{
val x = iter.next;
res = res ::: List((x, y)) // List((x, 1))
}
res.iterator
}
答案 1 :(得分:0)
我不知道第39行是什么,但为什么要重新编码地图函数来添加1?
你可以这样做:
val x = List(1,2,3,4,5).iterator
val y = x.map((_,1))
print(y.mkString(" "))
(1,1) (2,1) (3,1) (4,1) (5,1)