Scala之Fold:foldRight()与foldLeft()详解

Fold折叠:化简的一种特殊情况,foldRight():右折叠,foldLeft()左折叠
override /*TraversableLike*/
  def foldLeft[B](z: B)(f: (B, A) => B): B = {
    var acc = z
    var these = this
    while (!these.isEmpty) {
      acc = f(acc, these.head)
      these = these.tail
    }
    acc
  }

释义:
z: B 表示传入一个B[泛型]类型的zero零值
f: (B, A) => B  表示:传入一个名叫f的函数【scala可以将函数当做参数传递】,该函数需要传入两个参数,分别是B、A两种类型的参数,但返回值是B类型,也就是零值类型
foldLeft 函数名,柯理化的函数【参数列表2个:(z: B)、(f: (B, A) => B)】,该函数的返回值也是B类型

示例代码:

package sparkstreaming

object SparkStreamingDemo01 {

  def main(args: Array[String]): Unit = {

    val list = List(1,2,3,4)
    val i = list.foldLeft(1)((x,y)=>x-y)
    val i1 = list.foldRight(1)((x,y)=>x-y)

    println(i)
    println(i1)
  }
}

结果:
-9
-1
这两种算法原理究竟是怎样的呢?结果是如何得到的呢?
首先:foldLeft
val list = List(1,2,3,4)
val i = list.foldLeft(1)((x,y)=>x-y)

执行过程是:
第一次循环将零值传入函数f(x,y)=>x-y的左边x的位置,然后取出列表的第一个元素【these.head】,计算:res1 = f(1, 1)=>1-1 == 0 【伪代码】
第二次循环将第一次循环的结果【res1 == 0】继续当做左值传入x的位置,取出列表的第二个元素2放入y的位置,计算:res2 = f(res1, 2)=>0-2 == -2
第二次循环将第一次循环的结果【res2 == -2】继续当做左值传入x的位置,取出列表的第二个元素3放入y的位置,计算:res3 = f(res2, 3)=>-2-3 == -5
第四次循环将第一次循环的结果【res3 == -5】继续当做左值传入x的位置,取出列表的第二个元素4放入y的位置,计算:res4 = f(res3, 4)=>-5-4 == -9
也就是得到最终的结果是:-9

首先:foldRight
val list = List(1,2,3,4)
val i1 = list.foldRight(1)((x,y)=>x-y)

源码:可以看到其实是先将list做了一次翻转,然后还是调用的:foldLeft

1、List(1,2,3,4)翻转得到List(4, 3, 2, 1)
2、此时调用foldLeft参数列表没有变化,但是函数f(x,y)=>y-x,变成了:y-x

执行过程是:
第一次循环将零值传入函数f(x,y)=>x-y的左边x的位置,然后取出反转后的列表的第一个元素4【these.head】,计算:res1 = f(1, 4)=> 4-1 == 3 【伪代码】
第二次循环将第一次循环的结果【res1 == 3】继续当做左值传入x的位置,取出列表的第二个元素3放入y的位置,计算:res2 = f(res1, 3)=> 3-3 == 0
第二次循环将第一次循环的结果【res2 == 0】继续当做左值传入x的位置,取出列表的第二个元素2放入y的位置,计算:res3 = f(res2, 2)=> 2-0 == 2
第四次循环将第一次循环的结果【res3 == 2】继续当做左值传入x的位置,取出列表的第二个元素1放入y的位置,计算:res4 = f(res3, 1)=> 1-2 == -1
也就是得到最终的结果是:-1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

walking_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值