我對 Scala 中的 reduceleft 和 reduceRight 方法有點困惑。這是我正在測驗的片段:
val intList = List(5, 4, 3, 2, 1);
println(intList.reduceRight((curr, acc) => { //Reduce right me y is accumulator
println(s"First Curr = $curr, Acc = $acc")
curr - acc
}));
println(intList.reduceLeft((curr, acc) => { // List(1,2,3,4,5) // Accumulator is the first Element
println(s"Second Curr = $curr, Acc = $acc")
acc - curr}))
輸出如下所示:
First Curr = 2, Acc = 1
First Curr = 3, Acc = 1
First Curr = 4, Acc = 2
First Curr = 5, Acc = 2
3
Second Curr = 5, Acc = 4
Second Curr = -1, Acc = 3
Second Curr = 4, Acc = 2
Second Curr = -2, Acc = 1
在兩次迭代中,我觀察到的是,在 reduceRight 的情況下,我們有 ( curr, acc) [含義 curr 作為第一個引數傳遞,累加器作為第二個引數傳遞],而在reduceLeft我們有 ( acc, curr) 的情況下。
論據中的這種不一致背后是否有任何具體原因?
uj5u.com熱心網友回復:
讓我們使用一個小可視化:
reduceLeft:
a b c d e
acc1 = f(a, b) \/ / / /
acc2 = f(acc1, c) \/ / /
acc3 = f(acc2, d) \/ /
acc4 = f(acc3, e) \/
reduceRight:
a b c d e
\ \ \ \/ acc1 = f(d, e)
\ \ \/ acc2 = f(c, acc1)
\ \/ acc3 = f(b, acc2)
\/ acc4 = f(a, acc3)
引數的順序幫助我們記住引數的來源以及它們被評估的順序。因為不要混淆左關聯和右關聯操作非常重要:
- 任何視覺幫助都很重要,
acc在功能的正確方面書寫會使推理更容易 - 如果在這兩種情況下都在左側,則lambdas in
coll.reduceLeft(_ operation _)andcoll.reduceRight(_ operation _)會產生非常令人困惑的行為acc
想象一下,如果您定義了一個右結合運算子,例如a ** b(a 的 b 次冪)。數學中的求冪是右結合的,所以a ** b ** c應該表現得像a ** (b ** c)。有人決定使用 來計算這樣的用例rightReduce,因為它完全實作了這種行為。他們是這樣
List(a, b, c).reduceRight(_ ** _)
然后他們了解到有人決定acc應該在左側,因為他們希望它與reduceLeft. 這將與你從數學中獲得的每一種直覺更加不一致。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/372702.html
標籤:斯卡拉
