因此,我在stackoverflow上看到了另一位用户提出的这个问题,我试图在练习scala和spark时自己编写代码:
问题是从列表中找出每个键的平均值:
假设列表是:((1,1)、(1,3)、(2,4)、(2,3)、(3,1))
代码是:
val result = input.combineByKey(
(v) => (v, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)).
map{ case (key, value) => (key, value._1 / value._2.toFloat) }
result.collectAsMap().map(println(_))
因此,基本上上面的代码将创建一个类型为[Int,(Int,Int)]
的RDD,其中第一个Int
是键,值是(Int,Int)
,其中第一个Int
这里是使用相同键的所有值的相加,第二个Int
是键出现的次数。
我理解正在发生的事情,但出于某种原因,当我像这样重写代码时:
val result = input.combineByKey(
(v) => (v, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)).
mapValues(value: (Int, Int) => (value._1 / value._2))
result.collectAsMap().map(println(_))
当我使用mapValues而不是带有case
关键字的map时,代码不起作用。它给出了一个错误,说明error:not found:type/
将map与case和mapValues一起使用时有什么区别。因为我认为map值只需要取一个值(在本例中是a(Int,Int))并返回一个新值,键-值对的键保持不变。
没关系,我找到了一篇解决我问题的好文章:http://danielwestheide.com/blog/2012/12/12/the-neophytes-guide-to-scala-part-4-pattern-matching-anonymous-functions.html
如果其他人也有同样的问题,这就很好地解释了!
尝试
val result = input.combineByKey(
(v) => (v, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)).
mapValues(value => (value._1 / value._2))
result.collectAsMap().map(println(_))