之前的过程以下一种方式给了我累加器和每个组的计数:
val data: Array[(Int, (Double, Int))] = Array((2,(2.1463120403829962,7340)), (1,(1.4532644653720025,4280)))
结构为(groupId,(acum,count))
现在想减少以获得每个元组的总和:
(k1,(a1,n1)),(k2,(a2,n2))
需要:
(a1+a2),(n1+n2)
听起来像一个简单的任务,所以:
val mainMean = groups.reduce((acc,v)=>(acc._1 + v._1,acc._2 + v._2))
得到:
:33:错误:类型不匹配;发现:( Double,Int) 必需:字符串 val mainMean = groups.reduce((acc,v)=>(acc._1 + v._1,acc._2 + v._2))
也尝试过:
val mainMean = groups.reduce((k,(acc,v))=>(acc._1 + v._1,acc._2 + v._2))
告诉我:注意:元组不能在方法或函数参数中直接解构。 创建一个接受Tuple2的参数, 或考虑匹配匿名函数的模式
所以:
val mainMean = groups.reduce({case(k,(acc,n))=>(k,(acc._1+n._1,acc._1+n._2))})
并获取
错误:类型不匹配;发现:(Int,(Double,Int))必需:Int
我知道这是一个新手问题,但我被困在上面
答案 0 :(得分:1)
使用元组可能会遇到一些困难。
下面你可以看到工作代码,但让我解释一下。
val data = Array((2,(2.1463120403829962,7340)), (1,(1.4532644653720025,4280)))
def tupleSum(t1: (Int, (Double, Int)), t2: (Int, (Double, Int))): (Int, (Double, Int)) =
(0,(t1._2._1 + t2._2._1, t1._2._2 + t2._2._2))
val mainMean = data.reduce(tupleSum)._2
我们可以引入reduce
个参数,例如
data.reduce((tuple1, tuple2) => tupleSum(tuple1, tuple2))
其中tuple1
是一种累加器。在第一次迭代时,它获取数组的第一个值,并且每个下一个值都会添加到accumulator的值。
因此,如果您想使用模式匹配执行reduce,它将如下所示:
val mainMean = data.reduce((tuple1, tuple2) => {
val t1 = tuple1 match { case (i, t) => t }
val t2 = tuple2 match { case (i, t) => t }
// now t1 and t2 represents inner tuples of input tuples
(0, (t1._1 + t2._1, t1._2 + t2._2))}
)
UPD。
我重写了以前的列表添加类型注释和println语句。我希望这有助于明白这一点。之后有一些解释。
val data = Array((3, (3.0, 3)), (2,(2.0,2)), (1,(1.0,1)))
val mainMean = data.reduce((tuple1: (Int, (Double, Int)),
tuple2: (Int, (Double, Int))) => {
println("tuple1: " + tuple1)
println("tuple2: " + tuple2)
val t1: (Double, Int) = tuple1 match {
case (i: Int, t: (Double, Int)) => t
}
val t2: (Double, Int) = tuple2 match {
case (i: Int, t: (Double, Int)) => t
}
// now t1 and t2 represents inner tuples of input tuples
(0, (t1._1 + t2._1, t1._2 + t2._2))}
)
println("mainMean: " + mainMean)
输出将是:
tuple1: (3,(3.0,3)) // 1st element of the array
tuple2: (2,(2.0,2)) // 2nd element of the array
tuple1: (0,(5.0,5)) // sum of 1st and 2nd elements
tuple2: (1,(1.0,1)) // 3d element
mainMean: (0,(6.0,6)) // result sum
tuple1
和tuple2
类型为(Int, (Double, Int))
。我们知道它总是只有这种类型,这就是我们在模式匹配中只使用一种情况的原因。我们将tuple1解压缩到i: Int
和t: (Int, Double)
。只要我们对密钥不感兴趣,我们只返回t。现在t1
代表tuple1
的内部元组。与tuple2
和t2
相同的故事。