reduce和fold区别
reduce
reduce表示将列表,传入一个函数进行聚合运算。
reduce源码
- [A1 >: A]:reduce的参数A1必须为调用reduce数据集元素类型的子集
- reduceLeft(op):将匿名函数op传递给reduceLeft,底层调用reduceLeft实现
- op: (A1, A1) => A1:第一个A1为当前聚合后的变量,第二个A1为当前要聚合的元素。最终返回A1类型的变量
- reduce最终将原数据集聚合后生成一个元素
def reduce[A1 >: A](op: (A1, A1) => A1): A1 = reduceLeft(op)
reduceLeft源码
- 底层利用尾递归实现。调用reduce的数据集为空时抛出异常
实现过程:
- var first = true:定义标记为first为true
- var acc: B = 0.asInstanceOf[B]:声明一个个泛型B类型相同的变量(这里用到了擦拭法,直接写0.asInstanceOf[String]会报错)
- 第一个元素时,将第一个元素的值赋给acc。同时将标记为置为false
- 从第二个元素开始,进行递归调用匿名函数op。直到遍历完整个源数据集
- 将第一个元素和第二个元素进行操作,结果赋值给第一个元素,作为第一次聚合结果
- 将第三个元素和第一次聚合结果进行操作,将结果赋给第一个元素,作为第二次聚合结果
- 将第四个元素。。。。。
/** Applies a binary operator to all elements of this $coll,
* going left to right.
* $willNotTerminateInf
* $orderDependentFold
*
* @param op the binary operator.
* @tparam B the result type of the binary operator.
* @return the result of inserting `op` between consecutive elements of this $coll,
* going left to right:
* {
{
{
* op( op( ... op(x_1, x_2) ..., x_{n-1}), x_n)
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this $coll.
* @throws UnsupportedOperationException if this $coll is empty. */
def reduceLeft[B >: A](op: (B, A) => B): B = {
if (isEmpty)
throw new UnsupportedOperationException("empty.reduceLeft")
var first = true
var acc: B = 0.asInstanceOf[B]
for (x <- self) {
if (first) {
acc = x
first = false
}
else acc = op(acc, x)
}
acc
}
示例
scala> val a = List(1,2,3,4,5,6,7,8,9,10)
a: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
//集合中第一个元素赋给x,第二个赋给y
//相加后的元素赋给x,第三个元素赋给y