scala स्काला में foldLeft और कम करने के बीच अंतर




functional-programming higher-order-functions (6)

foldLeft अधिक सामान्य है, आप इसे मूल रूप से जो कुछ भी डालते हैं उससे बिल्कुल अलग कुछ उत्पन्न करने के लिए इसका उपयोग कर सकते हैं। जबकि reduceLeft हो सकता है reduceLeft केवल उसी प्रकार या संग्रह प्रकार के सुपर प्रकार का अंतिम परिणाम उत्पन्न कर सकता है। उदाहरण के लिए:

List(1,3,5).foldLeft(0) { _ + _ }
List(1,3,5).foldLeft(List[String]()) { (a, b) => b.toString :: a }

foldLeft अंतिम गुना परिणाम (प्रारंभिक मान का उपयोग करने में पहली बार) और अगले मान के साथ बंद हो जाएगा।

दूसरी ओर कम करें सूची पहले सूची से दो मूल्यों को जोड़ती है और बंद करने के लिए लागू होती है। इसके बाद यह शेष मूल्यों को संचयी परिणाम के साथ जोड़ देगा। देख:

List(1,3,5).reduceLeft { (a, b) => println("a " + a + ", b " + b); a + b }

यदि सूची खाली है तो foldLeft प्रारंभिक मान को कानूनी परिणाम के रूप में प्रस्तुत कर सकता है। दूसरी तरफ कम करें यदि कानूनी सूची में कम से कम एक मूल्य नहीं मिल रहा है तो उसके पास कानूनी मूल्य नहीं है।

मैंने foldLeft और reduceLeft बीच बुनियादी अंतर सीखा है

foldLeft:

  • प्रारंभिक मूल्य पारित किया जाना है

reduceLeft:

  • प्रारंभिक मूल्य के रूप में संग्रह का पहला तत्व लेता है
  • संग्रह खाली होने पर अपवाद फेंकता है

क्या कोई और अंतर है?

समान कार्यक्षमता वाले दो तरीकों के लिए कोई विशिष्ट कारण?


वास्तव में समझने के लिए कि आप गुना / कम करने के साथ क्या कर रहे हैं, इसे जांचें: http://wiki.tcl.tk/17983 बहुत अच्छी व्याख्या। एक बार जब आप गुना की अवधारणा प्राप्त कर लेते हैं, तो ऊपर दिए गए उत्तर के साथ कम हो जाएगा: list.tail.foldLeft (list.head) (_)


वास्तविक उत्तर देने से पहले यहां उल्लेख करने के लिए कुछ चीजें:

  • आपके प्रश्न में left कुछ भी करने की ज़रूरत नहीं है, बल्कि यह घटाने और तह करने के बीच के अंतर के बारे में है
  • अंतर बिल्कुल कार्यान्वयन नहीं है, केवल हस्ताक्षर देखें।
  • प्रश्न में विशेष रूप से स्कैला के साथ कुछ भी नहीं है, यह कार्यात्मक प्रोग्रामिंग की दो अवधारणाओं के बजाय है।

अपने प्रश्न पर वापस जाएं:

foldLeft का हस्ताक्षर यहां दिया गया है (जिस बिंदु को मैं बनाने जा रहा हूं foldRight लिए foldRight भी हो सकता है):

def foldLeft [B] (z: B)(f: (B, A) => B): B

और यहां कम करने का हस्ताक्षर है (फिर दिशा यहां कोई फर्क नहीं पड़ता)

def reduceLeft [B >: A] (f: (B, A) => B): B

ये दो बहुत समान दिखते हैं और इस प्रकार भ्रम पैदा करते हैं। reduceLeft का एक विशेष मामला है (जिस तरह से इसका मतलब है कि आप कभी-कभी उनमें से किसी एक का उपयोग कर एक ही चीज़ व्यक्त कर सकते हैं)।

जब आप कम List[Int] कहते हैं तो List[Int] यह सचमुच पूर्णांक की पूरी सूची को एक ही मान में कम कर देगा, जो कि Int (या Int का Int , इसलिए [B >: A] ) होने जा रहा है।

जब आप foldLeft को एक List[Int] पर कहते हैं तो यह पूरी सूची को फोल्ड करेगा (पेपर के टुकड़े को रोल करने की कल्पना करें) एक मूल्य में, लेकिन यह मान Int (इसलिए [B] ) से भी संबंधित नहीं होना चाहिए।

यहाँ एक उदाहरण है:

def listWithSum(numbers: List[Int]) = numbers.foldLeft((List[Int](), 0)) {
   (resultingTuple, currentInteger) =>
      (currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}

यह विधि एक List[Int] लेती है और एक Tuple2[List[Int], Int] या (List[Int] -> Int) । यह योग की गणना करता है और पूर्णांक की सूची के साथ एक टुपल देता है और यह योग है। जिस तरह से सूची पीछे की ओर लौटा दी जाती है, क्योंकि हमने foldLeft बजाय foldLeft उपयोग किया था।


संदर्भ के लिए, निम्न त्रुटि के साथ खाली कंटेनर पर लागू होने पर कम करें त्रुटि।

java.lang.UnsupportedOperationException: empty.reduceLeft

उपयोग करने के लिए कोड का कामकाज

myList foldLeft(List[String]()) {(a,b) => a+b}

एक संभावित विकल्प है। दूसरा एक reduceLeftOption संस्करण का उपयोग करना है जो एक विकल्प लपेटा परिणाम देता है।

myList reduceLeftOption {(a,b) => a+b} match {
  case None    => // handle no result as necessary
  case Some(v) => println(v)
}

स्कैला में कार्यात्मक प्रोग्रामिंग सिद्धांतों से (मार्टिन ओडरस्की):

फ़ंक्शन को reduceLeft लिए अधिक सामान्य फ़ंक्शन, foldLeft संदर्भ में परिभाषित किया जाता है।

foldLeft की तरह है, लेकिन एक अतिरिक्त पैरामीटर के रूप में एक accumulator z लेता है, जो एक खाली सूची पर foldLeft कहा जाता है जब foldLeft जाता है:

(List (x1, ..., xn) foldLeft z)(op) = (...(z op x1) op ...) op x

[कम करने के विरोध के रूप में, जो खाली सूची पर बुलाए जाने पर एक अपवाद फेंकता है।]

पाठ्यक्रम (व्याख्यान 5.5 देखें) इन कार्यों की सार परिभाषा प्रदान करता है, जो उनके मतभेदों को दर्शाता है, हालांकि वे पैटर्न मिलान और रिकर्सन के उपयोग में बहुत समान हैं।

abstract class List[T] { ...
  def reduceLeft(op: (T,T)=>T) : T = this match{
    case Nil     => throw new Error("Nil.reduceLeft")
    case x :: xs => (xs foldLeft x)(op)
  }
  def foldLeft[U](z: U)(op: (U,T)=>U): U = this match{
    case Nil     => z
    case x :: xs => (xs foldLeft op(z, x))(op)
  }
}

ध्यान दें कि foldLeft प्रकार U मान को लौटाता है, जो आवश्यक रूप से List[T] के समान प्रकार नहीं है, लेकिन कम करने वाला सूची सूची के समान प्रकार का मान देता है)।


reduceLeft बस एक सुविधा विधि है। यह बराबर है

list.tail.foldLeft(list.head)(_)






higher-order-functions