सामान्य तौर पर, सभी 6 गुना फ़ंक्शन एक संग्रह के प्रत्येक तत्व के लिए एक बाइनरी ऑपरेटर लागू करते हैं। प्रत्येक चरण का परिणाम अगले चरण पर पारित किया जाता है (बाइनरी ऑपरेटर के दो तर्कों में से एक पर इनपुट के रूप में)। इस तरह से हम कर सकते हैं cumulate परिणामस्वरूप।
reduceLeft
और reduceRight
एक परिणाम को कम करना।
foldLeft
और foldRight
प्रारंभ मूल्य का उपयोग करके एकल परिणाम को कम करें।
scanLeft
और scanRight
एक शुरुआत मूल्य का उपयोग करके मध्यवर्ती संचयी परिणामों का एक संग्रह तैयार करना।
संचय करें
बाएँ और आगे से ...
तत्वों के एक संग्रह abc
और एक बाइनरी ऑपरेटर के साथ add
हम पता लगा सकते हैं कि संग्रह के LEFT तत्व से (A से C तक) आगे बढ़ने पर विभिन्न गुना कार्य क्या करते हैं:
val abc = List("A", "B", "C")
def add(res: String, x: String) = {
println(s"op: $res + $x = ${res + x}")
res + x
}
abc.reduceLeft(add)
// op: A + B = AB
// op: AB + C = ABC // accumulates value AB in *first* operator arg `res`
// res: String = ABC
abc.foldLeft("z")(add) // with start value "z"
// op: z + A = zA // initial extra operation
// op: zA + B = zAB
// op: zAB + C = zABC
// res: String = zABC
abc.scanLeft("z")(add)
// op: z + A = zA // same operations as foldLeft above...
// op: zA + B = zAB
// op: zAB + C = zABC
// res: List[String] = List(z, zA, zAB, zABC) // maps intermediate results
राइट और पीछे की ओर से ...
यदि हम सही तत्व से शुरू करते हैं और पीछे की ओर जाते हैं (C से A की ओर) तो हम देखेंगे कि अब हमारे बाइनरी ऑपरेटर के लिए दूसरा तर्क परिणाम को जमा करता है (ऑपरेटर एक ही है, हमने अपनी भूमिकाओं को स्पष्ट करने के लिए तर्क नाम बदल दिए हैं ):
def add(x: String, res: String) = {
println(s"op: $x + $res = ${x + res}")
x + res
}
abc.reduceRight(add)
// op: B + C = BC
// op: A + BC = ABC // accumulates value BC in *second* operator arg `res`
// res: String = ABC
abc.foldRight("z")(add)
// op: C + z = Cz
// op: B + Cz = BCz
// op: A + BCz = ABCz
// res: String = ABCz
abc.scanRight("z")(add)
// op: C + z = Cz
// op: B + Cz = BCz
// op: A + BCz = ABCz
// res: List[String] = List(ABCz, BCz, Cz, z)
।
डी-cumulate
बाएँ और आगे से ...
यदि इसके बजाय हम के लिए गए थे डी-cumulate संग्रह का बायाँ तत्व से शुरू घटाव से कुछ परिणाम है, हम पहले तर्क के माध्यम से परिणाम cumulate हैं res
हमारे द्विआधारी ऑपरेटर की minus
:
val xs = List(1, 2, 3, 4)
def minus(res: Int, x: Int) = {
println(s"op: $res - $x = ${res - x}")
res - x
}
xs.reduceLeft(minus)
// op: 1 - 2 = -1
// op: -1 - 3 = -4 // de-cumulates value -1 in *first* operator arg `res`
// op: -4 - 4 = -8
// res: Int = -8
xs.foldLeft(0)(minus)
// op: 0 - 1 = -1
// op: -1 - 2 = -3
// op: -3 - 3 = -6
// op: -6 - 4 = -10
// res: Int = -10
xs.scanLeft(0)(minus)
// op: 0 - 1 = -1
// op: -1 - 2 = -3
// op: -3 - 3 = -6
// op: -6 - 4 = -10
// res: List[Int] = List(0, -1, -3, -6, -10)
राइट और पीछे की ओर से ...
लेकिन अभी xRight विविधताओं के लिए बाहर देखो! याद रखें कि xRight भिन्नताओं में संचयी मान (de-) हमारे बाइनरी ऑपरेटर के दूसरे पैरामीटर को पास किया गया है :res
minus
def minus(x: Int, res: Int) = {
println(s"op: $x - $res = ${x - res}")
x - res
}
xs.reduceRight(minus)
// op: 3 - 4 = -1
// op: 2 - -1 = 3 // de-cumulates value -1 in *second* operator arg `res`
// op: 1 - 3 = -2
// res: Int = -2
xs.foldRight(0)(minus)
// op: 4 - 0 = 4
// op: 3 - 4 = -1
// op: 2 - -1 = 3
// op: 1 - 3 = -2
// res: Int = -2
xs.scanRight(0)(minus)
// op: 4 - 0 = 4
// op: 3 - 4 = -1
// op: 2 - -1 = 3
// op: 1 - 3 = -2
// res: List[Int] = List(-2, 3, -1, 4, 0)
अंतिम सूची (-2, 3, -1, 4, 0) शायद वह नहीं है जो आप सहज रूप से उम्मीद करेंगे!
जैसा कि आप देख रहे हैं, आप जाँच सकते हैं कि आपका foldX क्या कर रहा है इसके बजाय बस एक scanX चला रहा है और प्रत्येक चरण में संचयी परिणाम को डीबग करें।
जमीनी स्तर