Raj*_*tty 191 functional-programming scala fold higher-order-functions
我已经学会了foldLeft
和之间的基本区别reduceLeft
foldLeft:
reduceLeft:
还有其他区别吗?
有两种方法具有相似功能的任何特定原因?
agi*_*eel 295
在给出实际答案之前,这里很少提及:
left
,而是减少和折叠之间的区别回到你的问题:
这是签名foldLeft
(也可能是foldRight
我要做的):
def foldLeft [B] (z: B)(f: (B, A) => B): B
Run Code Online (Sandbox Code Playgroud)
这里是签名reduceLeft
(这里的方向无关紧要)
def reduceLeft [B >: A] (f: (B, A) => B): B
Run Code Online (Sandbox Code Playgroud)
这两个看起来非常相似,从而引起了混乱.reduceLeft
是一种特殊情况foldLeft
(顺便说一下,你有时可以通过使用其中任何一种来表达同样的事情).
当你对它调用reduceLeft
say时,List[Int]
它会将整个整数列表减少为单个值,这将是类型Int
(或者是超类型Int
,因此[B >: A]
).
当你打电话foldLeft
给List[Int]
它时,它会将整个列表(想象滚动一张纸)折叠成一个值,但这个值不必与Int
(因此[B]
)相关.
这是一个例子:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Run Code Online (Sandbox Code Playgroud)
此方法采用a List[Int]
并返回a Tuple2[List[Int], Int]
或(List[Int], Int)
.它计算总和并返回一个带有整数列表的元组,它的总和.顺便说一下,列表是向后返回的,因为我们使用的是foldLeft
代替foldRight
.
观看One Fold以统治所有人以获得更深入的解释.
Kim*_*bel 189
reduceLeft
只是一种方便的方法.它相当于
list.tail.foldLeft(list.head)(_)
Run Code Online (Sandbox Code Playgroud)
tho*_*dge 44
foldLeft
更通用,您可以使用它来生成与您最初放入的内容完全不同的内容.而reduceLeft
只能生成相同类型或超类型集合类型的最终结果.例如:
List(1,3,5).foldLeft(0) { _ + _ }
List(1,3,5).foldLeft(List[String]()) { (a, b) => b.toString :: a }
Run Code Online (Sandbox Code Playgroud)
在foldLeft
将应用与最后折叠结果闭合(使用初始值第一次)和下一个值.
reduceLeft
另一方面,将首先组合列表中的两个值并将其应用于闭包.接下来,它将其余值与累积结果组合在一起.看到:
List(1,3,5).reduceLeft { (a, b) => println("a " + a + ", b " + b); a + b }
Run Code Online (Sandbox Code Playgroud)
如果列表为空,则foldLeft
可以将初始值显示为合法结果.reduceLeft
另一方面,如果在列表中找不到至少一个值,则没有合法值.
它们都在Scala标准库中的基本原因可能是因为它们都在Haskell标准库中(称为foldl
和foldl1
).如果reduceLeft
不是,它通常被定义为不同项目中的便利方法.
小智 5
作为参考,reduceLeft
如果应用于具有以下错误的空容器,则会出错.
java.lang.UnsupportedOperationException: empty.reduceLeft
Run Code Online (Sandbox Code Playgroud)
重新编写要使用的代码
myList foldLeft(List[String]()) {(a,b) => a+b}
Run Code Online (Sandbox Code Playgroud)
是一个潜在的选择.另一种方法是使用reduceLeftOption
返回Option包装结果的variant.
myList reduceLeftOption {(a,b) => a+b} match {
case None => // handle no result as necessary
case Some(v) => println(v)
}
Run Code Online (Sandbox Code Playgroud)