Scala中的fold和reduce理解

Scala中的fold和reduce理解

  • 折叠 fold
    • fold折叠应用场景
  • reduce

折叠 fold

折叠,也可以对集合数据进行简化 获取最终的一条结果
fold方法 可以传递2个部分的参数

  • 第一个部分表示集合之外的数据
  • 第二部分的参数表示数据进行的逻辑处理

Scala中的fold和reduce理解_第1张图片

Fold源码

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

foldLeft源码

def foldLeft[B](z: B)(op: (B, A) => B): B = {
    var result = z
    this foreach (x => result = op(result, x))
    result
  }

foldRight源码

def foldRight[B](z: B)(op: (A, B) => B): B =
    reversed.foldLeft(z)((x, y) => op(y, x))

fold折叠应用场景

将两个map进行合并 相同的key做累加 不同的key直接增加

map1.foldLeft(map2)((map, t) => {
     map(t._1) = map.getOrElse(t._1 , 0) + t._2
	 map
})

map1.foldLeft(map2)( (map, t) => {逻辑})

  1. 以map1为主体 一个一个的遍历其中的元素
  2. **map2整体是初始值 ** 所以放在第一个参数
  3. 根据代码提示,第二个参数 传的是一个 类型B 和 一个元组 返回的值是类型B
    所以 传个 (map, t), 这里的map 和 t 初次的 值
  4. map 初次值就是 初始值 map2 t的初始值就是map1遍历的第一个, 即 (a , 1)
    所以 明确有值 t = (a, 1) 然后从初始值map中 找key为a的值 没有就是返回0 两个值相加作为k的新的v值 (这就是第二个参数的逻辑)
  5. map保存的是每次两两操作的结果 map刚开始的值就是map2 说白了 map 就是中间值 (刚开始还要赋个初值)
  6. 而元组 t 就是map1的所有元组
  7. 因为map1有三个元祖 所以一共与map进行三次两两操作
    在这里插入图片描述

Scala中的fold和reduce理解_第2张图片

Scala中的fold和reduce理解_第3张图片
Scala中的fold和reduce理解_第4张图片
Scala中的fold和reduce理解_第5张图片

reduce

reduce 将多个数据 通过一定逻辑 减少一些加粗样式
Scala中的fold和reduce理解_第6张图片
比如 把四个变一个,
看上图 表示是 两两操作

先取 1  2       操作  结果 res1
然后 res1  3   操作 结果 res2
然后 res2 4     操作  结果 res3
最终结果 是 res3

下图 以操作为相加 示例:
Scala中的fold和reduce理解_第7张图片
即把集合中的数据两两相加变为1个 也看做 化简操作
求和 也可以用这样的方式 (也有sum函数可以完成求和操作 但是sum只能求和
但reduce里面的逻辑 是我们自己任意规定的 什么操作都可以 )
看源码 reduce 其实 调用的 reduceLeft 两者没有去别

Scala中的fold和reduce理解_第8张图片
Scala中的fold和reduce理解_第9张图片

reduceLeft 逻辑
Scala中的fold和reduce理解_第10张图片
很简单 :

  1. first 标记变量 看是否是集合的第一个数
  2. op 穿过来的操作函数 加 或 减
  3. self 传过来的集合 (1, 2, 3, 4)
  4. acc 定义时先转换类型 这里是Int类型, 它就是 每次两两操作的结果
  5. 在循环中,if里面就是第一次循环 将集合的第一个数给了acc
  6. 以后每次循环都进不了if
  7. else 就是 两两操作结果 再返回给acc 再循环

reduceRight
加粗样式
Scala中的fold和reduce理解_第11张图片

源码: 将集合反转然后使用reduceLeft 然后注意逻辑 将x y 互换位置

Scala中的fold和reduce理解_第12张图片

你可能感兴趣的:(Scala)