2011-10-08 12 views
7

मैं एक नौसिखिया स्केला को, मैं सिर्फ एक दिया स्ट्रिंग उल्टा करने के लिए एक सरल समारोह लिख रहा हूँ कर रहा हूँ:स्काला रिवर्स स्ट्रिंग

def reverse(s: String) : String 
    for(i <- s.length - 1 to 0) yield s(i) 

उपज एक scala.collection.immutable.IndexedSeq वापस देता है [चार] , और इसे एक स्ट्रिंग में परिवर्तित नहीं कर सकता। (या यह कुछ और है?)

मैं इस समारोह को कैसे लिखूं?

उत्तर

19

ध्यान दें कि वहाँ पहले से ही परिभाषित किया गया है समारोह:

scala> val x = "scala is awesome" 
x: java.lang.String = scala is awesome 

scala> x.reverse 
res1: String = emosewa si alacs 

लेकिन अगर आपको लगता है कि खुद ही करना चाहते हैं:

def reverse(s: String) : String = 
(for(i <- s.length - 1 to 0 by -1) yield s(i)).mkString 

या (कभी कभी यह until उपयोग करने के लिए बेहतर है, लेकिन शायद में नहीं उस मामले)

def reverse(s: String) : String = 
(for(i <- s.length until 0 by -1) yield s(i-1)).mkString 

इसके अलावा, ध्यान दें कि यदि आप उलटा गिनती का उपयोग करते हैं (बड़े ओ से कम से कम एक मूल्य के ne) आप नकारात्मक कदम निर्दिष्ट करना चाहिए या आप एक खाली सेट मिल जाएगा: ओम-nom-nom ने संकेत के रूप में

scala> for(i <- x.length until 0) yield i 
res2: scala.collection.immutable.IndexedSeq[Int] = Vector() 

scala> for(i <- x.length until 0 by -1) yield i 
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 
+0

धन्यवाद ओम-nom-nom, मैं इसे अपने आप को लागू करने के लिए तो मैं :) – Dzhu

7

, (by -1 पर ध्यान देना अन्यथा तुम सच में पुनरावृत्ति नहीं कर रहे हैं और अपने परिणाम खाली हो जाएगा)। आप जिस अन्य चाल का उपयोग कर सकते हैं वह collection.breakOut है।

यह भी इस तरह for समझ करने के लिए प्रदान किया जा सकता:

def reverse(s: String): String = 
    (for(i <- s.length - 1 to 0 by -1) yield s(i))(collection.breakOut) 

reverse("foo") 
// String = oof 

breakOut उपयोग करने का लाभ यह है कि यह mkString समाधान में के रूप में एक मध्यवर्ती संरचना बनाने से बचना होगा।

ध्यान दें: breakOutCanBuildFrom और बिल्डरों जो स्केला में पेश बदल दिया संग्रह पुस्तकालय की नींव का हिस्सा हैं लाभ है 2.8.0

+0

अच्छा एक सीख सकते हैं चाहता हूँ! इस तरह से 'ब्रेकऑट' के बारे में कभी सोचा नहीं। –

8

आप भी इस (एक पुनरावर्ती दृष्टिकोण का उपयोग कर बस में यह एक फेंक लिख सकता है मज़ा) के लिए

def reverse(s: String): String = { 
    if (s.isEmpty) "" 
    else reverse(s.tail) + s.head 
} 
+1

यह अनुकूलित नहीं किया जाएगा – gurghet

10

यहाँ एक लघु संस्करण है

def reverse(s: String) = ("" /: s)((a, x) => x + a) 

संपादित : या भी कम है, हम सनक से गुप्त

def reverse(s: String) = ("" /: s)(_.+:(_)) 

लेकिन मैं वास्तव में इस की सिफारिश नहीं होगा ...

+2

हाय लुइगी, क्या आप अपने कोड के लिए एक संक्षिप्त स्पष्टीकरण दे सकते हैं?धन्यवाद – Dzhu

+1

इच्छा है कि मैंने इस बारे में सोचा था। @Dzhu यह सिर्फ 'foldLeft' का उपयोग कर रहा है ('/:' केवल उस विधि के लिए एक छोटा सा नाम है) जो प्रारंभिक मान लेता है और उसके बाद अनुक्रम के प्रत्येक मान को बाएं से दाएं एक ऑपरेटर पर लागू करता है। इस मामले में, अनुक्रम स्ट्रिंग है और ऑपरेटर केवल स्ट्रिंग के पात्रों को परिणाम के लिए तैयार कर रहा है। –

+0

@Dzhu '" "/: s' इंफिक्स नोटेशन में एक विधि कॉल है। कॉल '' '' के साथ तर्क '' 'है, क्योंकि विधि '/:' '' 'में समाप्त होती है। यदि आप स्कैला दस्तावेज़ों में स्ट्रिंग को देखते हैं तो आपको यह नहीं मिलेगा क्योंकि यह सिर्फ जावा क्लास है, लेकिन आपको 'स्ट्रिंगऑप्स' मिलेगा, जिसमें स्ट्रिंग्स को पूरी तरह से परिवर्तित किया गया है, और यहां आपको '/:' विधि मिल जाएगी। यह curried है और एक दूसरा तर्क लेता है, जो (यहां) प्रकार का एक अनाम कार्य है (स्ट्रिंग, चार) => स्ट्रिंग'। यह भी देखें http://stackoverflow.com/q/7339618/770361, http://stackoverflow.com/questions/2293592/functional-programming-scala-map-and-fold-left/2303291#2303291 –

3

उपरोक्त सभी उत्तर सही हैं और यहाँ मेरी ले है है :

scala> val reverseString = (str: String) => str.foldLeft("")((accumulator, nextChar) => nextChar + accumulator) 
reverseString: String => java.lang.String = <function1> 

scala> reverseString.apply("qwerty") 
res0: java.lang.String = ytrewq