Scala中foldLeft和reduceLeft的区别
我已经了解了 foldLeft
和 reduceLeft
之间的基本区别
foldLeft:
- 必须传递初始值
reduceLeft:
- 首先采用 作为初始值的集合元素
- 如果集合为空,
会引发异常还有其他区别吗?
有什么具体原因让两种方法具有相似的功能?
I have learned the basic difference between foldLeft
and reduceLeft
foldLeft:
- initial value has to be passed
reduceLeft:
- takes first element of the collection as initial value
- throws exception if collection is empty
Is there any other difference ?
Any specific reason to have two methods with similar functionality?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
它们都在 Scala 标准库中的根本原因可能是因为它们都在 Haskell 标准库中(称为
foldl
和foldl1
)。如果reduceLeft
不是,它通常会在不同的项目中被定义为一种方便的方法。The basic reason they are both in Scala standard library is probably because they are both in Haskell standard library (called
foldl
andfoldl1
). IfreduceLeft
wasn't, it would quite often be defined as a convenience method in different projects.来自 Scala 函数式编程原则 (Martin Odersky):
[相对于
reduceLeft
,在空列表上调用时会引发异常。]该课程(参见讲座 5.5)提供了这些函数的抽象定义,这说明了它们的差异,尽管它们在模式的使用上非常相似匹配和递归。
请注意,
foldLeft
返回一个U
类型的值,该值不一定与List[T]
类型相同,但 reduceLeft 返回一个值与列表类型相同)。From Functional Programming Principles in Scala (Martin Odersky):
[as opposed to
reduceLeft
, which throws an exception when called on an empty list.]The course (see lecture 5.5) provides abstract definitions of these functions, which illustrates their differences, although they are very similar in their use of pattern matching and recursion.
Note that
foldLeft
returns a value of typeU
, which is not necessarily the same type asList[T]
, but reduceLeft returns a value of the same type as the list).要真正了解您在使用折叠/减少做什么,
检查这个:http://wiki.tcl.tk/17983
很好的解释。一旦你掌握了折叠的概念,
减少将与上面的答案一起:
list.tail.foldLeft(list.head)(_)
To really understand what are you doing with fold/reduce,
check this: http://wiki.tcl.tk/17983
very good explanation. once you get the concept of fold,
reduce will come together with the answer above:
list.tail.foldLeft(list.head)(_)
Scala 2.13.3,演示:
输出:
Scala 2.13.3, Demo:
outputs:
在给出实际答案之前,这里要提一下:
left
没有任何关系,而是关于减少和折叠之间的区别。回到你的问题:
这是
foldLeft
的签名(也可以是foldRight
来表达我要表达的观点):这是
reduceLeft
的签名(这里方向并不重要)这两个看起来非常相似,因此引起了混乱。
reduceLeft
是foldLeft
的特例(顺便说一句,这意味着您有时可以使用它们中的任何一个来表达相同的内容)。当您在
List[Int]
上调用reduceLeft
时,它实际上会将整个整数列表减少为单个值,该值的类型为Int
(或Int
的超类型,因此[B >: A]
)。当您在
List[Int]
上调用foldLeft
时,它会将整个列表(想象一下卷起一张纸)折叠成单个值,但该值不会折叠甚至必须与Int
相关(因此是[B]
)。下面是一个示例:
此方法采用
List[Int]
并返回Tuple2[List[Int], Int]
或(List[Int], Int )
。它计算总和并返回一个包含整数列表及其总和的元组。顺便说一下,列表是向后返回的,因为我们使用了foldLeft
而不是foldRight
。观看一折统治一切以获得更深入的解释。
Few things to mention here, before giving the actual answer:
left
, it's rather about the difference between reducing and foldingBack to your question:
Here is the signature of
foldLeft
(could also have beenfoldRight
for the point I'm going to make):And here is the signature of
reduceLeft
(again the direction doesn't matter here)These two look very similar and thus caused the confusion.
reduceLeft
is a special case offoldLeft
(which by the way means that you sometimes can express the same thing by using either of them).When you call
reduceLeft
say on aList[Int]
it will literally reduce the whole list of integers into a single value, which is going to be of typeInt
(or a supertype ofInt
, hence[B >: A]
).When you call
foldLeft
say on aList[Int]
it will fold the whole list (imagine rolling a piece of paper) into a single value, but this value doesn't have to be even related toInt
(hence[B]
).Here is an example:
This method takes a
List[Int]
and returns aTuple2[List[Int], Int]
or(List[Int], Int)
. It calculates the sum and returns a tuple with a list of integers and it's sum. By the way the list is returned backwards, because we usedfoldLeft
instead offoldRight
.Watch One Fold to rule them all for a more in depth explanation.
reduceLeft
只是一个方便的方法。它相当于reduceLeft
is just a convenience method. It is equivalent tofoldLeft
更通用,您可以使用它来生成与最初放入的内容完全不同的内容。而reduceLeft
只能生成相同类型或超类型的最终结果的集合类型。例如:foldLeft 将应用最后折叠结果(第一次使用初始值)和下一个值的闭包。
另一方面,reduceLeft 将首先组合列表中的两个值并将它们应用于闭包。接下来它将把其余的值与累积结果结合起来。请参阅:
如果列表为空,
foldLeft
可以将初始值呈现为合法结果。另一方面,如果reduceLeft
在列表中找不到至少一个值,则它没有合法值。foldLeft
is more generic, you can use it to produce something completely different than what you originally put in. WhereasreduceLeft
can only produce an end result of the same type or super type of the collection type. For example:The
foldLeft
will apply the closure with the last folded result (first time using initial value) and the next value.reduceLeft
on the other hand will first combine two values from the list and apply those to the closure. Next it will combine the rest of the values with the cumulative result. See:If the list is empty
foldLeft
can present the initial value as a legal result.reduceLeft
on the other hand does not have a legal value if it can't find at least one value in the list.作为参考,如果应用于空容器,
reduceLeft
将出错并出现以下错误。重新编写要使用的代码
是一种潜在的选择。另一种方法是使用
reduceLeftOption
变体,它返回 Option 包装的结果。For reference,
reduceLeft
will error if applied to an empty container with the following error.Reworking the code to use
is one potential option. Another is to use the
reduceLeftOption
variant which returns an Option wrapped result.