如果我运行:
List(1, 4, 3, 9).reduce {(a, b) => println(s"$a + $b"); a + b}
Run Code Online (Sandbox Code Playgroud)
结果是:
1 + 4
5 + 3
8 + 9
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用reduceLeft
而不是reduce
,它还会打印:
1 + 4
5 + 3
8 + 9
Run Code Online (Sandbox Code Playgroud)
我认为reduce
以这种方式减少值的序列:
(1+4) + (3+9)
(5) + (12)
(17)
Run Code Online (Sandbox Code Playgroud)
reduceLeft
和之间的真正区别是什么reduce
?
Dim*_*ima 14
看一下两个函数的类型:
\ndef reduce[B >: A](op: (B, B) => B): B \ndef reduceLeft[B >: A](op: (B, A) => B): B\n
Run Code Online (Sandbox Code Playgroud)\nop
请注意, in的第二个参数reduceLeft
是A
(与元素类型相同),而 in reduce
it 是B
(与返回值相同)。
这是一个重要的区别。在reduce中的操作必须是结合的,这意味着您可以将列表拆分为多个段,分别对每个段应用操作,然后再次将其应用于结果以进行组合。
\n当您想要并行执行操作时,这一点很重要:reduce
可以并行应用于列表的不同部分,然后可以组合结果。
reduceLeft
另一方面,只能按顺序工作(从左到右,顾名思义),操作不必是关联的,并且可以期望它的第二个参数始终是序列的元素(第一个参数 \xe2\ x80\x93\xc2\xa0 到目前为止的操作结果);
考虑
\n val sum = (1 to 100).reduce(_ + _) \n
Run Code Online (Sandbox Code Playgroud)\n这会产生与 相同的结果(1 to 100).reduceLeft(_ + _)
,只是前者可以并行化。\n另一方面:
val strings = (1 to 100).reduceLeft[Any](_.toString + ";" + _.toString) \n
Run Code Online (Sandbox Code Playgroud)\n不应该写成reduce
(尽管在这个人为的示例中,它可以,甚至只要您坚持串行处理就可以工作),因为结果取决于将元素馈送到操作的顺序。
归档时间: |
|
查看次数: |
1846 次 |
最近记录: |