有人可以提供一些例子来说明如何
真的习惯了吗?我认为它们是 reduce / fold 方法的快捷方式,但没有关于它们如何在 Scala 文档中实际使用的示例,并且无法在 StackOverflow 上搜索 / 搜索它们。
我个人更喜欢and的/:
and:\
形式。两个原因: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 - 它基本上完全相同,只是该值似乎是从右侧推入的。我必须说,我倾向于避开foldRight
scala,因为它是如何实现的(即错误地)。
/:
是foldLeft
和:\
的同义词foldRight
。
但请记住,:
它/:
适用于它右侧的对象。
假设您知道这(_ * _)
是一个等效于 的匿名函数(a, b) => a * b
,并且 foldLeft 和 foldRight 的签名是
def foldLeft [B] (z: B)(f: (B, A) ⇒ B): B
def foldRight [B] (z: B)(f: (A, B) ⇒ B): B
即它们是 curried 函数,采用起始值和将起始值/累加器与列表中的项目相结合的函数,一些示例是:
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 的函数是相反的,但如果您在脑海中想象折叠,这是有道理的。
Rex Kerr 在这里写了关于折叠的好答案。在接近尾声时,您可以看到 foldLeft 和 foldRight 的快捷语法示例。