我想计算Class2
Class2.b == 444
的总金额。在这种情况下,有4个。
object Main extends App {
class Class1(val a: Int)
class Class2(val b: Int)
val source = Seq[(Class1, Seq[Class2])](
(new Class1(1), Seq(new Class2(12), new Class2(2), new Class2(3), new Class2(4))),
(new Class1(2), Seq(new Class2(222), new Class2(22), new Class2(33), new Class2(444))),
(new Class1(3), Seq(new Class2(33), new Class2(444), new Class2(3), new Class2(14))),
(new Class1(4), Seq(new Class2(44), new Class2(444), new Class2(43), new Class2(444)))
)
// acc and item are Any!
val res = source fold(0) { (acc, item) => acc + item._2.count(_.b == 444) }
}
答案 0 :(得分:4)
第一个错误:你不能在这里使用无点符号:
val res = source.fold(0){ (acc, item) => acc + item._2.count(_.b == 444) }
<console>:10: error: value _2 is not a member of Any
val res = source.fold(0){ (acc, item) => acc + item._2.count(_.b == 444) }
^
第二个错误:fold
方法接受元素类型的超类型作为第一个参数:
def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1
在这种情况下,它是Any
((Class1, Seq[Class2])
和Int
的常见超类型。)
您必须使用foldLeft
:
val res = source.foldLeft(0){ (acc, item) => acc + item._2.count(_.b == 444) }
//res: Int = 4
要使用fold
,您必须将source
的元素转换为Int
:
val res = source.map{ _._2.count(_.b == 444) }.fold(0){_ + _}
// res: Int = 4
请注意,您可以使用sum
代替fold(0){_ + _}
,也可以使用view
来避免创建中间集合:
val res = source.view.map{ _._2.count(_.b == 444) }.sum
// res: Int = 4
方法fold
与foldLeft
不同。这是方法aggregate
的一个特例:
scala> (1 to 4).par.fold(0){ (a, e) => println(a -> e); 0 }
(0,1)
(0,4)
(0,3)
(0,2)
(0,0)
(0,0)
(0,0)
fold
用于并行收集将集合拆分为多个部分(Seq(1)
,Seq(2)
,Seq(3)
,Seq(4)
),使用操作{{1}聚合每个部分}:{(a, e) => println(a -> e); 0}
,(0,1)
,(0,2)
,(0,3)
然后使用相同的操作聚合结果:(0,4)
3次。
一般来说(方法(0,0)
)你必须提供不同的方法来聚合每个部分并组合来自不同部分的结果,如下所示:
aggregate