list scala 当前位置 遍历_【Scala笔记——道】Scala List 遍历 foldLeft / foldRight详解...

2023-11-20

HOF foldLeft / foldRight

foldLeft 和 foldRight 都是对于 List 遍历的 高阶函数。是对列表遍历过程中进行函数操作的高阶函数抽象。

List 遍历

假设有两个方法如下

// 求和

def sum(ints: List[Int]): Int = ints match {

case Nil => 0

case Cons(x, xs) => x + sum(xs)

}

//阶乘

def product(ds: List[Double]): Double = ds match {

case Nil => 1.0

case Cons(x, xs) => x * product(xs)

}

可以看到这两个方法体很相似,基本可以概括为

case Nil=> #ReturnBack#

case Cons(head, tail) => #递归遍历 + function 操作#

foldRight

定义输入 参数如下

li : List [A]

b: Nil返回结果

f : ( a : A, b: B) => B 函数操作

将这种方式进行抽象为如下流程

foldLeft简单的 流程可以理解为如下

从列表末尾开始执行函数操作 f, 具体 为 f0 = f ( li [li.lenth -1] , b), 此时 f0 为改末尾节点执行函数结果

在列表上一节点执行函数, 此时 的b 为一节点的函数执行结果,具体为 f1 = f ( li [li.lenth -2] , b = f0)

一直递归到列表头

具体实现如下

def foldRight[A, B](li : List[A], b : B)(f: (A, B)=> B) : B = li match {

case Nil => b

case Cons(head, tail) => f(head, foldRight(tail, b)(f))

}

foladRight 实际上是先对列表进行递归,并将每个节点执行的方法先压入栈中,到最后拿到 b 后再从栈中一步恢复执行。

foldLeft

foladRight中我们的递归操作实际上是依靠栈实现的,但这就会造成一个问题:在列表过大时,会造成栈溢出。

如何解决 栈溢出 的问题?我们比较容易想到的一个办法是 尾递归进行优化

foldRight 相当于从尾部进行递归操作,而栈的引入主要是保存 首次递归到尾部时,之前节点执行 函数操作的状态。

这就是foldLeft 的主要思想

具体实现如下

def foldLeft[A, B](li : List[A], b: B)(f: (B, A)=> B) : B = li match {

case Nil => b

case Cons(head, tail) => foldLeft(tail, f(b, head))(f)

}

实际上foldLeft其实是可以通过尾递归进行优化,因此foldLeft在大List情况下,并不会产生栈溢出情况

再看foldRight和foldLeft

再回到最初的程序,具体的foladRight和foldLeft实现如下

def sumFoldRight(ns: List[Int]) : Int ={

foldRight(ns, 0)((x, y) => x + y)

}

def producetFoldRight(ns : List[Double]): Double = {

foldRight(ns, 1.0)(_*_)

}

def sumFoldLeft(ns: List[Int]): Int = {

foldLeft(ns, 0)(_+_)

}

def produceFoldLeft(ns: List[Double]): Double = {

foldLeft(ns, 1.0)(_*_)

}

看起来 foldRight 和 foldLeft 对于这两种方法实现都是没有问题,但是实际上 foldRight 和 foldLeft 实际上是不同的。

foldRight 的从头遍历实际上我们理解的从末尾开始执行函数,但foldLeft实际上并不是,我们在foldLeft计算时实际上是把List的头当作尾部计算。

这里会带来一个问题相同的 执行函数 在foldLeft和 foldRight可能执行结果并不同。这两者相同的条件相当于我们从头开始函数计算或者从未开始函数计算对结果并没有影响。由于 加法和乘法都满足交换率,因此在这里是没有问题的。换句话说,foldLeft并不能直接替换foldRight,除非操作函数是幂等的

这里我们写一个 int2String方法

def int2StringFoldRight[A](as: List[A]): String = {

foldRight(as, "-")(_+_)

}

def int2StringFoldLeft[A](as: List[A]): String = {

foldLeft(as, "-")(_+_)

}

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

val list = Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Cons(6, Nil))))))

println(int2StringFoldRight(list))

println("dropLastFoldRight\n")

println(int2StringFoldLeft(list))

println("int2StringFoldLeft\n")

}

执行结果如下

123456-

dropLastFoldRight

-123456int2StringFoldLeft

这样很明显就可以看出才非幂等函数里边,foldRight 和 foldLeft 可以进行替换,并且建议使用 foldLeft 通过尾递归进行优化,但对于非幂等函数,需要慎重使用foldLeft,更建议使用foldRight。

foldLeft适用场景

大表

幂等

foldRight适用场景

小表

非幂等

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

list scala 当前位置 遍历_【Scala笔记——道】Scala List 遍历 foldLeft / foldRight详解... 的相关文章

  • Android简单的反编译嵌入例子

    简单的反编译嵌入例子 1 创建一个源工程 2 创建一个转接类 如Ed Sdk java 3 在转接类里面建立一个空方法A 方法A需要被调用 4 创建一个库工程 2 创建一个库转接类 如Ed Sdk java 类名方法名变量名完全相同 6 在
  • Java和Scala中泛型类的继承

    Java和Scala中泛型类的继承 1 泛型的学习 2 泛型类的继承 1 泛型的学习 参考 Java编程的逻辑一书 马骏昌编写的 对泛型的讲解很详细 这里着重补充一下关于泛型类的继承 2 泛型类的继承 这里主要有三种情况 存在父类 clas
  • 利用TBDBitmapData对象查找两张图片上的不同

    利用TBDBitmapData对象查找两张图片上的不同 从右上角开始利用双层循环遍历两图上的所有象素点 并相互比较 不完整代码如下 procedure TForm1 Button5Click Sender TObject var Bmp1
  • [人工智能-深度学习-53]:循环神经网络 - LSTM长短记忆时序模型的简化:门控循环网络GRU模型

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 121599096 目录 第1章 前序知
  • HTML开始历程Day01

    1 HTML 其实就是网页基本结构 CSS 功能 美化网页 不让网页太单调 JS 功能 能让网页动起来 产生很多的交互行为 HTML是什么 Hyper Text Markup Language 超文本标记语言 服务器端口号 路径位置 HTM
  • Linux下用命令行编译运行Java总结

    最近使用腾讯云的Cloud Studio写Java 只能使用命令行进行编译运行 趁此机会 学习一下Linux的一些常用命令 平时windows下IDE用习惯了 现在用命令行进行编译运行 发现其实问题还是挺多的 所以写下这篇文章 1 java
  • WordPress主题开发 — 模版循环(条件判断、多个循环、新建查询和文章循环)

    循环是 WordPress 通过主题模板文件输出文章的默认机制 在循环中 WordPress 遍历当前页面获取到的所有文章 然后使用主题中的模版标签将其格式化并输出 我们可以用 WordPress 循环来做很多事情 例如 在网站首页显示多个
  • java IO、NIO、AIO详解

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 一 IO流 同步 阻塞 二 NIO 同步 非阻塞 三 NIO2 异步 非阻塞 正文 回到顶部 概述 在我们学习Java的IO流之前 我们都要了解几个关键词 同步与异步 sy
  • hyperledger fabric介绍

    一 Hyperledger Fabric介绍 2015年 Linux基金会启动了Hyperledger项目 目标是发展跨行业的区块链技术 Hyperledger Fabric是Hyperledger中的一个区块链项目 包含一个账本 使用智能
  • 使用php生成6位密码大全,php生成随机产生六位数密码的代码

    php生成随机产生六位数密码的代码 供大家学习参考 复制代码代码示例 随机产生六位数密码Begin function randStr len 6 format ALL switch format case ALL chars ABCDEFG
  • 《CTF特训营》学习总结——Reverse:逆向分析概述

    一 逆向分析的主要方法 逆向分析主要是将二进制机器码进行反汇编得到汇编代码 在汇编代码的基础上 进行功能分析 经过反编译生成的汇编代码中缺失了源代码中的符号 数据结构等信息 因此需要尽可能地通过逆向分析还原以上信息 以便分析程序原有逻辑和功
  • qt样式表设置边框_QT 样式风格 & 样式表 (QStyleSheet)

    QT Style的机制和GTK的Style机制很类似 基本上就是 定义了一个基础的Style类 在Style类里面定义一系列的绘图相关函数接口 具体风格的Style类实现了这些函数接口 在控件的实现中 控件的绘图函数调用Style类的绘图函
  • 导航电子地图的制作过程

    背景知识 1 导航原理 现代导航通过实时测定运动客体的当前位置及速度 方向等运动参数 以此为基础通过分析和计算 确定若干条符合某些条件要求如 距离 速度 时间 方向 的路线和行驶方案 然后利用系统进行引导和控制客体沿确定路线行驶 并提供必要
  • 软件测试基础——WEB测试模块

    软件测试工程师体系 web测试模块 web测试模块脑图 本文内容以脑图形式展示
  • 什么是接口测试,如何做接口测试?

    比起点点点的功能测试 接口测试 显得专业又高大上 也因此让有些初级测试人员 望而生畏 别担心 其实接口测试也是功能测试的一种 它是针对接口进行的功能测试 写在前面 本文参考了茹炳晟老师的 测试工程师 全栈技术进阶与实践 并结合自己的理解进行
  • Kafka 监控系统Eagle 使用教程 V1.4.0

    1 下载安装zookeeper 2 下载安装kafka 3 下载安装kafka eagle http download kafka eagle org tar zvxf kafka eagle bin 1 4 0 tar gz 4 配置JA
  • 命令注入漏洞(1)

    命令注入漏洞原理 其实命令注入漏洞也叫命令行注入漏洞 此漏洞是指web应用程序中调用了系统可执行命令的函数 而且输入的参数是可控的 如果黑客拼接了注入命令 就可以进行非法操作了 靶机搭建 链接 https pan baidu com s 1
  • 用栈实现括号匹配问题

    通过观察 我们可以发现 括号匹配的字符串 左括号与右括号数目一定相等 且遇到右括号时 必定有与之相匹配的括号在之前最近出现过 这样 可以整理解决问题的思路如下 假设有一串带括号的字符串 依次访问每一个字符 遇到左括号入栈 遇到右括号时 取栈
  • 有关bool(布尔)类型在C语言中的应用

    文章目录 前言 一 bool类型是什么 二 使用举例 总结 前言 由于学习过程中接触到了bool类型 产生了浓厚的兴趣 便写下这一篇文章来阐述bool类型的大概情况 一 bool类型是什么 bool 布尔 是在C99标准中引入的类型 是以英

随机推荐

  • GPT-4来了,但大模型的诸多未解之谜仍然未解

    导语 在3月14日 OpenAI 的 GPT 4 正式发布 它拥有多模态能力 可以接受图像输入并理解图像内容 可接受的文字输入长度增加到 3 2 万个 token 在多种专业和学术基准测试中取得好成绩 然而 功能强大的 GPT 4 与早期的
  • 关于串口调试助手上面的DTR和RTS

    开发调试过程中 突然XCOM串口调试助手无法接发数据 而用了sscom却可以实现正常功能 emo了很久 对比了两个软件对串口的设置 包括波特率 停止位 校验位等设置 也没发现异端 以为是sscom这个软件禁用了XCOM 后来仔细比对发现 X
  • DDR布线要求及拓扑结构分析

    在DDR的PCB设计中 一般需要考虑等长和拓扑结构 等长比较好处理 给出一定的等长精度通常是PCB设计师是能够完成的 但对于不同的速率的DDR 选择合适的拓扑结构非常关键 在DDR布线中经常使用的T型拓扑结构和菊花链拓扑结构 下面主要介绍这
  • 动手学数据分析 Task3

    动手学数据分析 Task3 一 concat merge join 二 groupby 一 concat merge join concat方法可以在两个维度上拼接 默认纵向凭借 axis 0 拼接方式默认外连接 pd concat obj
  • window全局对象的全局变量与脚本的全局变量间的关系

    如果脚本中的变量声明出现在命名元素之前 那这个变量的存在就会组织元素获取他的window属性 而如果脚本中的变量声明出现在命名元素之后 那么变量的显示赋值会覆盖该属性的隐式值
  • 数据库系列MySQL:优化配置文件

    配置流程 1 MySQL文件目录中后缀名为 ini文件的就是MySQL的默认配置文件 2 程序启动会先加载配置文件中的的配置 之后才会真正启动程序 3 更改完配置文件设置后需要重新启动服务端才可以生效 优化方案一 服务器内存 4 8GB k
  • 删除C++ std::string字符串中的空格

    介绍一个使用标准库算法删除std string字符串中空格的方法 代码如下 std string str1 Hello world str1 erase std remove if str1 begin str1 end unsigned
  • unity: C#的Action Event Delegate的异同

    目录 一 Action 二 Event 三 Action和Event区别 四 Delegate 总结 Action Event Delegate的异同 前言 Action Event和Delegate都是C 语言中的重要概念 分别用于管理函
  • Human3.6M数据集下载

    Download H36M annotations mkdir data cd data wget http visiondata cis upenn edu volumetric h36m h36m annot tar tar xf h3
  • 利用Apache Tika分页解析pdf文件内容

    Apache Tika 实现pdf文档分页提取内容 Apache Tika是一个多功能的文档内容提取工具 可以提取多种类型的文档内容 常用的如pdf office等格式 网上的例子基本上都是提取整篇文档内容 实际上用Tika提取pdf等文档
  • QT 实现点击窗口以外任何位置即关闭窗口

    bool QTipLabel eventFilter QObject o QEvent e switch e gt type ifdef Q DEAD CODE FROM QT4 MAC case QEvent KeyPress case
  • LeetCode-----第八题-----字符串转换整数 (atoi)

    字符串转换整数 atoi 难度 中等 请你来实现一个 atoi 函数 使其能将字符串转换成整数 首先 该函数会根据需要丢弃无用的开头空格字符 直到寻找到第一个非空格的字符为止 接下来的转化规则如下 如果第一个非空字符为正或者负号时 则将该符
  • Java-spring相关八股

    1 Java中有哪几种方式来创建线程执行任务 继承Thread类 public class zhouyuThread extends Thread public static void main string args zhouyuThre
  • XL4015-ADJ 5A 大电流DC-DC原理图分享

    如有问题 请加扣扣群 460189483 最近咨询LM2596S ADJ 3A芯片竟然已经10元rmb了 于是找到5A负载能力的XL4015 ADJ 正品4元 以后就用这个代替啦 通过比较发现 XL4015的温度低一点 效率高一点 电流大一
  • Android 实时获取SurfaceView渲染的内容截图

    近期的需求 偶尔需要获取当前SurfaceView上渲染的内容视图 因为是通过网页端控制的 类似预览功能吧 百度了好久 没找到能用的 无意间发现了这个类PixelCopy java 网上没什么介绍 安卓系统封装的一个类PixelCopy j
  • 解决plt.title()中文显示问题

    我们直接用plt title 默认是显示英文 如图 应该在代码前加这几行代码就行了 解决中文显示问题 plt rcParams font sans serif SimHei plt rcParams axes unicode minus F
  • VMware虚拟机安装Ubuntu系统步骤详解

    VMware虚拟机安装Ubuntu系统步骤详解 Ubuntu系统介绍 VMware安装Ubuntu步骤 一 Ubuntu系统的下载 二 VMware workstation的下载安装 三 配置Ubuntu虚拟机系统 四 VMware安装Ub
  • vue插件(vue-print-nb)实现打印功能

    vue插件vue print nb实现打印功能 1 安装vue print nb 2 引入Vue项目 3 在组件中使用 4 vue print nb插件优化 1 安装vue print nb Vue2 0版本安装方法 npm install
  • 重命名文件或目录(renameTo)

    File or directory with old name File file new File oldname File or directory with new name File file2 new File newname R
  • list scala 当前位置 遍历_【Scala笔记——道】Scala List 遍历 foldLeft / foldRight详解...

    HOF foldLeft foldRight foldLeft 和 foldRight 都是对于 List 遍历的 高阶函数 是对列表遍历过程中进行函数操作的高阶函数抽象 List 遍历 假设有两个方法如下 求和 def sum ints