有人可以提供一些例子
实际上习惯了?我假设它们是reduce / fold方法的快捷方式,但是没有关于它们如何在Scala文档中实际使用的例子,并且它们无法在StackOverflow上进行谷歌/搜索。
答案 0 :(得分:14)
我个人更喜欢/:
和:\
形式的foldLeft
和foldRight
。有两个原因:
它具有更自然的感觉,因为您可以看到您正在将值推入集合的左/右并应用函数。那是
(1 /: ints) { _ + _ }
ints.foldLeft(1) { _ + _ }
两者都是等价的,但我倾向于认为前者强调我对正在发生的事情的直觉。如果你想知道如何这种情况发生(即方法似乎是在值1而不是集合上调用),那是因为以冒号结尾的方法是右关联的。这可以在标准库中其他地方的::
,+:
等等中看到。
Function2
参数的顺序与折叠元素的顺序和折叠的顺序相同:
(b /: as) { (bb, a) => f(bb, a) }
// ^ ^ ^ ^
// ^ ^ ^ ^
// B A B A
比以下方面更好:
as.foldLeft(b) { (bb, a) => f(bb, a) }
虽然我承认在IDE支持体面之前这是一个非常重要的差异:现在IDEA可以通过一个简单的CTRL-P来告诉我预期的功能
我希望:\
如何使用foldRight也很明显 - 它基本上完全一样,只是值似乎是从右侧推入的。我必须说,因为它的实现方式(即错误地),我倾向于在scala中远离foldRight
。
答案 1 :(得分:10)
/:
是foldLeft
的同义词和:\
的{{1}}。
但请记住,foldRight
会使:
适用于其右侧的对象。
假设您知道/:
是一个等同于(_ * _)
的匿名函数,而且foldLeft和foldRight的签名是
(a, b) => a * b
即。它们是带有起始值的curried函数和将起始值/累加器与列表中的项组合在一起的函数,例如:
def foldLeft [B] (z: B)(f: (B, A) ⇒ B): B
def foldRight [B] (z: B)(f: (A, B) ⇒ B): B
与
相同List(1,2,3).foldLeft(1)(_*_)
和
(1 /: List(1,2,3))(_*_)
中缀表示法中的是
List(1,2,3).foldRight(1)(_*_)
与
相同(List(1,2,3) foldRight 1)(_*_)
添加您自己的收藏和功能,享受!
使用短((List(1,2,3) :\ 1)(_*_)
和/:
)符号记住的事情是,因为您使用中缀符号,所以需要在第一部分周围加上括号以便选择正确地填写第二个参数列表。另外,请记住,foldLeft和foldRight的函数是相反的方式,但是如果你想象你的头部折叠那么它是有意义的。
答案 2 :(得分:3)
Rex Kerr写了很多关于折叠here的答案。接近结尾,您可以看到foldLeft和foldRight的快捷语法示例。