2011-08-20 16 views
7

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

कहें कि मेरे पास एक तरीका है जो एक ट्यूपल देता है और मैं इन मानों के साथ कुछ करना चाहता हूं।

उदा। अगर मैं एक निश्चित बिंदु पर एक स्ट्रिंग विभाजित है और टुकड़े

def backToFront(s: String, n:Int) = s.splitAt(n)... 

रिवर्स करना चाहते मैं

val (a, b) = s.splitAt(n) 
b + a 

या

List(s.splitAt(n)).map(i => i._2 + i._1).head 

(काम करता है (अस्थायी चर और नए बयान की आवश्यकता है) कर सकते हैं , लेकिन थोड़ा गंदे लगता है, केवल इसके लिए एक तत्व सूची बना रहा है) या

s.splitAt(n).swap.productIterator.mkString 

(इस विशेष उदाहरण के लिए काम करता है, लेकिन केवल इसलिए कि swap विधि होती है जो मैं चाहता हूं, इसलिए यह बहुत सामान्य नहीं है)।

zipped टुपल्स पर विधि सूचियों के tuples के लिए लगता है।

एक और उदाहरण के रूप में, आप एक बयान में ('a, 'b, 'c) को ('b, 'a, 'c) में कैसे बदल सकते हैं?

उत्तर

9

टुपल्स सिर्फ सुविधाजनक रिटर्न प्रकार हैं, और यह नहीं माना जाता है कि आप इसके साथ जटिल जोड़ देंगे। स्केल मंचों पर भी discussion समान था।

अंतिम उदाहरण के बारे में, पैटर्न-मिलान से कुछ भी बेहतर नहीं मिला।मुझे लगता है कि आप बहुत लंबा दिनों की बात प्रतीक्षा करने के लिए (मैं कहना चाहता हूँ नहीं होना चाहिए

import shapeless.syntax.std.tuple._ 

val s = "abcdefgh" 
val n = 3 

s.splitAt(n).rotateRight[shapeless.Nat._1].mkString("", "", "") // "defghabc" 

:

('a, 'b, 'c) match { case (a, b, c) => (b, a ,c) } 
+0

पैटर्न मिलान अच्छा है! 's.splitAt (n) मिलान {केस (ए, बी) => बी + ए}' पहले भाग के लिए काम करता है –

+2

यह एक दयालुता है कि मानक पुस्तकालय में 'fold' विधि नहीं है; तो आप बस 's.splitAt (n) .fold ((ए, बी) => बी + ए)', और यह भी अधिक कुशल हो सकता है। (हाँ, निश्चित रूप से मैंने अपना खुद का बना दिया है।) –

+0

मोड़ इसके लिए एक अच्छा नाम है। मैंने अपना जवाब अपडेट किया। –

7

दुर्भाग्य से, tuples पर अंतर्निहित विधियां pretty limited हैं।

हो सकता है कि आप अपने निजी पुस्तकालय में इस तरह के कुछ चाहते हैं,

def fold2[A, B, C](x: (A, B))(f: (A, B) => C): C = f(x._1, x._2) 
def fold3[A, B, C, D](x: (A, B, C))(f: (A, B, C) => D): D = f(x._1, x._2, x._3) 
उचित निहित रूपांतरण के साथ

, तुम कर सकते हो,

scala> "hello world".splitAt(5).swap.fold(_ + _) 
res1: java.lang.String = " worldhello" 

scala> (1, 2, 3).fold((a, b, c) => (b, c, a)) 
res2: (Int, Int, Int) = (2,3,1) 

पिछले अभिव्यक्ति के लिए एक वैकल्पिक "पाइप होगा "ऑपरेटर |> (इसे स्कालाज़ या here से प्राप्त करें),

scala> ('a, 'b, 'c) |> (t => (t._2, t._3, t._1)) 
res3: (Symbol, Symbol, Symbol) = ('b,'c,'a) 

यह अच्छा होगा यदि आवश्यक एनोटेशन के लिए नहीं,

scala> ("hello ", "world") |> (((_: String) + (_: String)).tupled) 
res4: java.lang.String = hello world 
2

कैसे इस बारे में?

s.splitAt(n) |> Function.tupled(_ + _) 

[संपादित करें: बस ध्यान दें कि कार्य करने के लिए आपके तर्क उलट दिए गए हैं। उस मामले में, आप प्लेसहोल्डर वाक्य रचना देने के लिए करना होगा और बदले के लिए जाते हैं: (। के रूप में @ 4e6 द्वारा दिखाया गया है) s.splitAt(n) |> Function.tupled((a, b) => b + a)]

अपने पिछले उदाहरण के लिए, कुछ भी एक पैटर्न मैच की तुलना में बेहतर नहीं सोच सकते हैं

0
shapeless की वर्तमान विकास संस्करण के साथ

, आप टपल खोल के बिना इस लक्ष्य को हासिल कर सकते हैं) अंतिम पंक्ति के तरीकों के वाक्यविन्यास से पहले साफ हो जाएं, और आप बस

s.splitAt(n).rotateRight(1).mkString 
संबंधित मुद्दे