scala tuple अनपैक करना


91

मुझे पता है कि यह सवाल कई बार अलग-अलग तरीकों से सामने आया है। लेकिन यह अभी भी मेरे लिए स्पष्ट नहीं है। क्या निम्नलिखित को प्राप्त करने का एक तरीका है।

def foo(a:Int, b:Int) = {}

foo(a,b) //right way to invoke foo

foo(getParams) // is there a way to get this working without explicitly unpacking the tuple??

def getParams = {
   //Some calculations
   (a,b)  //where a & b are Int
}

11
क्या होगा यदि फू कुछ वर्ग का निर्माता है?
स्काउट

जवाबों:


107

यह दो चरणों वाली प्रक्रिया है। पहले एक फंक्शन में फू ट करें, फिर उस पर ट्यूप्ड कॉल करें ताकि वह एक ट्यूल का फंक्शन बना सके।

(foo _).tupled(getParams)

3
क्या यह साफ नहीं होगा यदि स्काला ने केवल तुपल्स के साथ शुरू करने के लिए तर्कों के बारे में सोचा?
हेनरी स्टोरी

12
हां, यह बहुत साफ हो जाएगा अगर स्काला इसे ट्यूपल्स और तर्क सूचियों के संचालन से एकीकृत करेगा। मैंने जो सुना है, उसमें बहुत सारे गैर-स्पष्ट किनारे-मामले हैं जिन्हें बनाने के लिए सावधानी से निपटने की आवश्यकता होगी। जहां तक ​​मुझे पता है, ट्यूपल्स और तर्क सूचियों का एकीकरण इस समय स्काला रोडमैप पर नहीं है।
डेव ग्रिफ़िथ

2
बस जोड़ने के लिए, अगर फू साथी की वस्तु का कारखाना तरीका है, तो कोई भी (Foo.apply _) का उपयोग कर सकता है। टैप किया हुआ (getParams)
RAbraham

55

@ डेव-ग्रिफ़िथ पर मर चुका है।

आप भी कॉल कर सकते हैं:

Function.tupled(foo _)

यदि आप "क्षेत्र के लिए मेरे द्वारा पूछी गई" की तुलना में अधिक जानकारी के लिए भटकना चाहते हैं, तो Functionकरीने के लिए आंशिक रूप से लागू किए गए कार्यों (और ) में निर्मित विधियां भी हैं । कुछ इनपुट / आउटपुट उदाहरण:

scala> def foo(x: Int, y: Double) = x * y
foo: (x: Int,y: Double)Double

scala> foo _
res0: (Int, Double) => Double = <function2>

scala> foo _ tupled
res1: ((Int, Double)) => Double = <function1>

scala> foo _ curried
res2: (Int) => (Double) => Double = <function1>

scala> Function.tupled(foo _)
res3: ((Int, Double)) => Double = <function1>

// Function.curried is deprecated
scala> Function.curried(foo _)
warning: there were deprecation warnings; re-run with -deprecation for details
res6: (Int) => (Double) => Double = <function1>

जिसमें कई संस्करण सूचियों के साथ करी संस्करण को शामिल किया गया है:

scala> val c = foo _ curried
c: (Int) => (Double) => Double = <function1>

scala> c(5)
res13: (Double) => Double = <function1>

scala> c(5)(10)
res14: Double = 50.0

अंत में, जरूरत पड़ने पर आप बिना सोचे-समझे / अनप्लग भी कर सकते हैं। Functionइसके लिए बिल्डिंस हैं:

scala> val f = foo _ tupled
f: ((Int, Double)) => Double = <function1>

scala> val c = foo _ curried
c: (Int) => (Double) => Double = <function1>

scala> Function.uncurried(c)
res9: (Int, Double) => Double = <function2>

scala> Function.untupled(f)
res12: (Int, Double) => Double = <function2>


20

Function.tupled(foo _)(getParams) या डेव द्वारा सुझाया गया।

संपादित करें:

आपकी टिप्पणी का जवाब देने के लिए:

क्या होगा यदि फू कुछ वर्ग का निर्माता है?

उस स्थिति में, यह ट्रिक काम नहीं करेगी।

आप अपनी कक्षा के साथी ऑब्जेक्ट में एक फ़ैक्टरी विधि लिख सकते हैं और फिर applyपूर्वोक्त तकनीकों में से एक का उपयोग करके इसकी विधि का टुप्ड संस्करण प्राप्त कर सकते हैं।

scala> class Person(firstName: String, lastName: String) {
     |   override def toString = firstName + " " + lastName
     | }
defined class Person

scala> object Person {
     |   def apply(firstName: String, lastName: String) = new Person(firstName, lastName)
     | }
defined module Person

scala> (Person.apply _).tupled(("Rahul", "G"))
res17: Person = Rahul G

case classतों के साथ आपको applyमुफ्त में एक विधि के साथ एक साथी वस्तु मिलती है , और इस तरह यह तकनीक case classतों के साथ उपयोग करने के लिए अधिक सुविधाजनक है ।

scala> case class Person(firstName: String, lastName: String)
defined class Person

scala> Person.tupled(("Rahul", "G"))
res18: Person = Person(Rahul,G)

मुझे पता है कि कोड का एक बहुत दोहराव है, लेकिन अफसोस ... हमारे पास मैक्रोज़ (अभी तक) नहीं है! ;)


3
यहां अंतिम उदाहरण में, आप थोड़ा मुंडन कर सकते हैं ... मामले की कक्षाओं के लिए साथी ऑब्जेक्ट्स हमेशा उपयुक्त फ़ंक्शनएन विशेषता का विस्तार करते हैं। तो अंतिम पंक्ति Person.tupled(("Rahul", "G")) यह हाथ से लिखी गई साथी वस्तुओं में भी करना आसान हो सकता है।
डेविड विंसलो

3

मैं कुछ अन्य उत्तरों की सराहना करता हूं जो आपके द्वारा पूछे जाने के करीब थे, लेकिन मैंने वर्तमान परियोजना के लिए एक और फ़ंक्शन जोड़ने के लिए आसान पाया जो टपल मापदंडों को विभाजित मापदंडों में परिवर्तित करता है:

def originalFunc(a: A, b: B): C = ...
def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab)

1

अब, आप फू को लागू कर सकते हैं और इसे टुप्ले 2 वर्ग के समान ले सकते हैं।

def foo(t: Tuple2[Int, Int]) = {
  println("Hello " + t._1 + t._2)
  "Makes no sense but ok!"
}

def getParams = {
  //Some calculations
  val a = 1;
  val b = 2;
  (a, b) //where a & b are Int
}

// So you can do this!
foo(getParams)
// With that said, you can also do this!
foo(1, 3)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.