【Scala原理系列】 foldLeft 由来原理场景用法示例详解

微信好友恢复全攻略(2025年3月更新) 适用于仅被拉黑场景(成功率100%)针对7天内误删场景(成功率78%) 阅读详情

【Scala原理系列】 foldLeft 由来原理用法示例详解

由来

在Scala的方法中,可以有多个参数列表。这种特性允许我们将参数分组,并以不同的方式使用和传递它们。

在Scala集合API中的Iterable特质中定义了一个具有多参数列表的方法foldLeft:

foldLeft 是 Scala 集合类的一个高阶函数,用于对集合中的元素进行累积计算。它的原理基于函数式编程中的折叠(fold)操作。

foldLeft 的原理是通过遍历集合中的元素,逐步将每个元素应用于指定的累积函数,并将结果传递给下一个元素,最终得到一个最终的累积结果。

trait Iterable[A]:
  ...
  def foldLeft[B](z: B)(op: (B, A) => B): B
  ...

foldLeft方法将一个两个参数的函数op应用于初始值z和该集合的所有元素,从左到右进行计算。

以下是其使用示例:

val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val res = numbers.foldLeft(0)((m, n) => m + n)
println(res) // 55

使用场景

多参数列表的建议使用场景包括:

1. 推断类型:

在Scala中,类型推断按照每个参数列表进行。假设你有以下方法:

def foldLeft1[A, B](as: List[A], b0: B, op: (B, A) => B) = ???

你可能希望以以下方式调用它,但会发现它无法编译通过:

def notPossible = foldLeft1(numbers, 0, _ + _)

你需要像以下方式之一调用它:

def firstWay = foldLeft1[Int, Int](numbers, 0, _ + _)
def secondWay = foldLeft1(numbers, 0, (a: Int, b: Int) => a + b)

这是因为Scala无法推断出函数_ + _的类型,因为它仍在推断A和B。通过将参数op移动到自己的参数列表中,A和B会在第一个参数列表中进行推断。这些推断的类型将在第二个参数列表中可用,_ + _将与推断的类型(Int, Int) => Int匹配。

2. 隐式参数

要将特定参数指定为隐式参数,必须将它们放置在它们自己的隐式参数列表中。例如:

def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ???

3. 偏应用函数:

当使用较少数量的参数列表调用方法时,它将产生一个以缺失的参数列表作为其参数的函数。这被称为偏应用函数。例如:

val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val numberFunc = numbers.foldLeft(List[Int]()) _

val squares = numberFunc((xs, x) => xs :+ x*x)
println(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

val cubes = numberFunc((xs, x) => xs :+ x*x*x)
println(cubes)  // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)

不适合的场景

虽然 foldLeft 是一个非常有用的函数,但并不适用于所有场景。以下是一些可能不适合使用 foldLeft 的情况:

  1. 需要并行计算:foldLeft 是一种顺序计算的操作,每次迭代都依赖前一次迭代的结果。如果您需要在并行环境下执行计算,可以考虑使用其他支持并行操作的函数,如 fold 或 reduce。

  2. 对集合进行早期终止:foldLeft 会遍历整个集合并计算最终累积值,无法在中途提前结束。如果您希望在某些条件下提前终止计算,那么使用 foldLeft 可能不是最合适的选择。可以考虑使用其他函数,如 takeWhile 或 find 来实现这种需求。

  3. 不需要累积结果:如果您只关注集合中的某些元素,而不需要累积结果,那么使用 foreach 更加直接和简洁。foreach 函数可以对集合中的每个元素应用一个函数,而无需显式地进行累积操作。

  4. 性能要求较高的大型数据集:尽管 foldLeft 在处理小型数据集时效果很好,但对于大型数据集,由于每次迭代都会产生新的累积值,可能会导致性能下降。在这种情况下,可以考虑使用更高效的聚合操作,如 fold 或 reduce。

总之,尽管 foldLeft 是一个功能强大的函数,但在某些特定场景下可能不是最佳选择。在选择适当的函数时,要根据具体需求和性能要求进行评估和比较,并选择最合适的函数来满足您的目标。

与"柯里化"的比较

有时你可能会看到具有多个参数列表的方法被称为“柯里化”。

柯里化是将一个接受多个参数的函数转换为一系列每次只接受一个参数的函数的技术。

我们不鼓励使用“柯里化”一词来指代Scala中的多参数列表,原因有两点:

  1. 在Scala中,多参数和多参数列表是直接指定和实现的,而不是从单参数函数派生出来的。

  2. 这可能会与Scala标准库的curried和uncurried方法产生混淆,这些方法根本不涉及多参数列表。

尽管如此,在多参数列表和柯里化之间确实存在相似之处。尽管在定义时它们是不同的,但在调用时可能看起来完全相同,就像下面的例子一样:

// 使用多参数列表的版本
def addMultiple(n1: Int)(n2: Int) = n1 + n2

// 两种不同的方式得到柯里化版本
def add(n1: Int, n2: Int) = n1 + n2
val addCurried1 = (add _).curried
val addCurried2 = (n1: Int) => (n2: Int) => n1 + n2

// 无论如何,所有三个调用方式都相同
addMultiple(3)(4)  // 7
addCurried1(3)(4)  // 7
addCurried2(3)(4)  // 7

示例

package org.example.scala

object leftFoldTest extends App{
  // 示例1:列表中元素的乘积
  val numbers = List(2, 3, 4, 5)
  val product = numbers.foldLeft(1)(_ * _)
  println("Product of numbers: " + product)  // 预期输出: Product of numbers: 120

  // 示例2:字符串反转
  val str = "Scala"
  val reversedStr = str.foldLeft("")((acc, char) => char + acc)
  println("Reversed string: " + reversedStr)  // 预期输出: Reversed string: alacS

  // 示例3:计算列表中偶数的平均值
  val values = List(2, 4, 6, 8, 10)
  val evenSumAndCount = values.foldLeft((0, 0)) { case ((sum, count), num) =>
    if (num % 2 == 0) (sum + num, count + 1) else (sum, count)
  }
  val evenAverage = evenSumAndCount match {
    case (sum, count) if count > 0 => sum.toDouble / count
    case _ => 0.0
  }
  println("Even average: " + evenAverage)  // 预期输出: Even average: 6.0

  // 示例4:自定义对象列表的操作
  case class Person(name: String, age: Int)
  val people = List(Person("Alice", 25), Person("Bob", 30), Person("Charlie", 35))
  val totalAge = people.foldLeft(0)((sum, person) => sum + person.age)
  println("Total age: " + totalAge)  // 预期输出: Total age: 90

}
//Product of numbers: 120
//Reversed string: alacS
//Even average: 6.0
//Total age: 90

参考链接

YOLOv8改进 | Conv篇 | DWRSeg扩张式残差助力小目标检测 (附修改后的C2f+Bottleneck) 本文内容给大家带来的DWRSeg中的DWR模块来改进YOLOv8中的C2f和Bottleneck模块,主要针对的是小目标检测,主要创新点可以总结如下:多尺度特征提取机制的深入研究和创新的DWR模块和SIR模块的提出这种方法使得网络能够更灵活地适应不同尺度的特征,从而更准确地识别和分割图像中的物体。通过本文你能够了解到DWRSeg的基本原理和框架,并且能够在你自己的网络结构中进行添加(DWRSeg需要增加一定的计算量一个DWR模块大概增加0.4GFLOPs)。 阅读详情

相关推荐

LDO稳定性分析

根据补偿方式和拓扑结构的不同,三个极点之间的相互位置有可能发生变化,但 是 LDO 通常采用较大的输出电容 Cout,以及较大的调整管也会导致较大的 Cpar, 所以 p1、p2 通常位于较低的频率处,而 p3 和 z1 则由于 Resr较小会位于较高的频 率处。不过幸运的是,对于较大的 Cout来说,只要选择合适的 Resr,就可以将左半平面零点 Z1 的频率降低,甚至使 Z1 进入单位增益带宽内,左半平面零点的进入将对相位有所改善,这不仅可以消除振荡的风险,还可以在单位增益频率处得到较好的相位裕度。

模拟芯片设计 1593

Scala中foldLeft的简单使用总结

Scala中foldLeft的简单使用总结 由于工作需要,博主在写spark相关业务代码时用到foldLeft,经过一番搜寻发现很多文章对这个函数的讲解,于初学者来说不好理解,特此我来做个简单易懂的分析总结,供大家参考。 若发现理解上的偏差,还请多指教。 源码分析 def seq: TraversableOnce[A] 上面两段代码是scala.collection.TraversableOnc...

Scala中foldLeft的简单使用总结 2万+

基于OSPF技术的某企业网络设计(完整文档+ENSP拓扑图)

主要对网络规划与设计,以企业网络为背景,对某个中型企业网络进行规划设计,该企业总部在南京,在常州有一个分公司,需要实现总部和分公司能够访问外网,能够让分公司内的用户或主机访问总部服务器的资源,并且保证数据的安全性。在这次总部企业网络设计中,考虑到资金的问题,核心层部署2台核心三层交换机,负责转发总部内部用户的流量,并充当内部用户网关,能够实现内部不同网段的用户之间的连通性。对于一些对网络比较敏感的企业或用户,对网络的要求较高,对于网络的稳定性和安全性也有较高的要求。

qq1325513482的博客 2万+

scala foldLeft foldRight

聊一聊scala的foldLeft方法和foldRight方法。

upupfeng的博客 1086

手把手教你用示波器抓取MIPI D-PHY波形:从LP11到HS Burst的完整信号解析

本文详细介绍了使用示波器精准捕获MIPI D-PHY信号的关键技巧,包括探头选择、示波器参数设置、信号状态解析及高级触发配置。通过实战案例和波形分析,帮助工程师快速识别从LP11到HS Burst的各种信号状态,解决常见的信号完整性问题,提升调试效率。

weixin_30471561的博客 563

Cadence Design Entry HDL 使用教程

Cadence Design Entry HDL 使用教程 前言 cadence Design Entry HDL是cadence内部集成的一款板级的EDA设计工具,早期叫 concept HDL。其为cadence最早的原配板级电路图绘制工具,只不过由于后来cadence收购了orcad然后就将旗下的capture CIS收入其中,由于后者使用起来上手简单,所以后者更为大家所熟知。虽然大家对...

uio159753的博客 4万+

Scala的foldLeft与foldRight详解

foldLeft与foldRight是特质TraversableOnce定义的高阶函数,直译过来为向左折叠和向右折叠。

RainTicking的博客 979

SAP ERP销售应收&成本科目确定

ERP作为业财一体软件,其中最核心的就是业务与财务模块的自动集成,无需财务进行手工做账,提高工作效率的同时降低人工操作产生的误差。今天浅浅的分享一下SD模块生成会计凭证时,借贷项确定的系统配置。一般项目上借贷项、科目都有FICO提供,但是具体的集成配置是在SD这边。

weixin_43657667的博客 1569

(秒懂)图解scala的foldleft和foldright

foldLeft: 比如 List(1,7,2,9).foldLeft(0)(_-_) 其中0是初始值 一般情况下对于foldLeft可以这么解决:0-1-7-2-9 = -19 还可以画一个图(别吐槽): 本栗子的操作就是_-_,也就是各元素相减,所以我们从底端开始就得到(((0-1)-7)-2)-9= -19 foldRight 骚微变一下初值 List(1,7,2,9).foldRight......

无知是恶 5310

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 1190

【Bug已解决】codex file edit fails / Write operation denied — CodeX CLI 文件编辑失败解决方案

CodeX CLI 编辑文件时报写入被拒绝,本质是沙箱限制或权限不足。文中给出配置允许目录、修复权限、Git stash 管理冲突等完整方案。

一键难忘的博客 4301

Scala reduceLeft与foldLeft、Range和Stream

目录 一、reduceLeft和foldLeft的基本解释 reduceLeft表达式: foldLeft表达式: 二、reduceLeft和foldLeft的实例应用 三、Range 定义Range 生成Range 四、Stream 定义Stream 生成Stream 访问Stream元素 一、reduceLeft和foldLeft的基本解释 reduceLef...

小宫主的博客 809

【Mini KITTI】KITTI数据集简介 — Mini KITTI

为了快速进行算法调试、训练、评估和验证,以及快速下载,制作了一个mini kitti数据集,数据集的文件目录结构与完整KITTI数据集保持一致。其中,小型的KITTI数据集,即 mini kitti保存了20个训练样本和5个测试样本。下载地址为:。 关于KITTI各个部分的介绍请分别参考以下内容: ...

叶子的博客 7537

Scala的foldLeft和foldRight

第一次看到/:这样的代码在别人的代码里,感觉很好奇,这是什么符号呢?

OopsOutOfMemory盛利的博客 2万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【离线版下载】一次装好高通USB驱动,手机插上电脑就能ADB调试

如果你连过一次高通芯片的手机、结果设备管理器里蹦出来一个"未知设备",就懂这种折腾有多烦。这个项目把各种版本的高通 USB 驱动(Qualcomm USB Driver)打包进了一个 All in One 安装包,不用再按手机型号一个个找驱动。装上之后手机往电脑一插,系统自己完成识别,完事。做 Android 开发、手机调试,手机又是高通平台的,能省不少时间。 ## 高通USB驱动集合好在哪

gitblog_00994的博客 664

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C盘飘红了?Dism++三步腾空间、补更新、留后路

下午想装个软件,C盘直接飘红,系统更新还在后台转圈。别再叠加清理插件了——试试Dism++,基于微软官方CBS组件服务技术(官方的组件管理服务)的开源优化工具。本文带你走完"腾空间→补更新→留后路"整条路,每步做完都有看得见的反馈。 ## 先认脸:它和旧做法差在哪 🧭 | 你的旧做法 | 它的做法 | | --- | --- | | 装清理插件删临时文件,C盘红着还是红 | 调用微软官方CB

gitblog_00968的博客 852

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Scala :foldLeft foldRight min max

Scala的foldLeft和foldRight1.foldLeft和foldRight1.foldLeft定义:def foldLeft[B](z:B)(f:(B, A) => B): B={ var acc = z var these = this while (!these.isEmpty) { acc = f(acc, these.head)

power0405hf的专栏 761

Scala fold foldLeft foldRight的区别

问题背景 fold、foldLeft、foldRight是scala常用的列表规约操作,最终实现的效果也差不多,但他们的区别在哪里呢?发现网上文章很多,能讲清楚的很少。 问题描述 三个函数都是给定一个起始值和一个规约函数对列表进行规约,例如: scala> List(4,5,6).fold(0)(_ + _) res3: Int = 15 scala> List(4,5,6).foldLeft(0)(_ + _) res4: Int = 15 scala> List(4,5,

Jacob_Zheng的博客 522

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

HOF foldLeft / foldRightfoldLeft 和 foldRight 都是对于 List 遍历的 高阶函数。是对列表遍历过程中进行函数操作的高阶函数抽象。List 遍历假设有两个方法如下// 求和def sum(ints: List[Int]): Int = ints match {case Nil => 0case Cons(x, xs) => x + sum(...

weixin_39634985的博客 246

FP in Scala 第 10 章练习 12 详解:用 Monoid 统一实现 Foldable 的 foldRight / foldLeft / foldMap

`Foldable` 是函数式编程中描述"可折叠容器"的核心抽象,而 `Monoid`(幺半群)是"可结合、有单位元"的最小代数结构。练习 12 是《Functional Programming in Scala》第 10 章(monoids)的经典转折点:**不再为每个容器手工编写折叠逻辑,而是把 foldRight、foldLeft、foldMap 全部定义在 `Foldable` trait

gitblog_00881的博客 338

fpinscala 练习精讲:用 foldLeft 实现 reverse 反转列表(《Functional Programming in Scala》第 3 章)

本篇文章围绕 fpinscala 仓库中 [answerkey/datastructures/12.answer.md](https://link.gitcode.com/i/593508cde3e31fa3745e54f8b8ec8609) 给出的练习 12 答案展开,讲解如何在自定义 `List` 数据结构上用 `foldLeft` 实现 `reverse`(列表反转)。读完本文,你将理解 `

gitblog_00191的博客 23

fold,foldLeft和foldRight区别与联系

从本质上说,fold函数将一种格式的输入数据转化成另外一种格式返回。fold, foldLeft和foldRight这三个函数除了有一点点不同外,做的事情差不多。我将在下文解释它们的共同点并解释它们的不同点。   我将从一个简单的例子开始,用fold计算一系列整型的和。 val numbers = List(5, 4, 8, 6, 2)

浅汐 786

Scala的foldLeft和foldRight和/:和:\

代码:结果:/:是foldLeft的缩写,:\是foldRight的缩写a/:b 结果得是b

shine 2238

【Scala笔记——道】Scala List 遍历 foldLeft / foldRight详解

HOF foldLeft / foldRight foldLeft 和 foldRight 都是对于 List 遍历的 高阶函数。是对列表遍历过程中进行函数操作的高阶函数抽象。 List 遍历 假设有两个方法如下 // 求和 def sum(ints: List[Int]): Int = ints match { ca...

weixin_34194087的博客 167

Secret powers of foldLeft() in Scala

Secret powers of foldLeft() in Scala foldLeft() method, available for all collections in Scala, allows to run a given 2-argument function against consecutive elements of that collection, where th

我的博客 1369

Scala:fold,foldLeft和foldRight区别与联系

从本质上说,fold函数将一种格式的输入数据转化成另外一种格式返回。fold, foldLeft和foldRight这三个函数除了有一点点不同外,做的事情差不多。我将在下文解释它们的共同点并解释它们的不同点。   我将从一个简单的例子开始,用fold计算一系列整型的和。 val numbers = List(5, 4, 8, 6, 2)

qq_32253371的博客 429
上一篇: Scala copy 方法
下一篇: Spark PipelineModel
BigDataMLApplication
博客等级 码龄11年 7363粉丝 565原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

BigDataMLApplication

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

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

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

打赏作者

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

抵扣说明:

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

余额充值