2011-10-08 70 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 

此外,請注意,如果您使用反向計數(從更大的o NE少一個值)應指定負步長或你會得到一個空集:

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

感謝OM-NOM-NOM,我要實現它自己,所以我可以學習:) – Dzhu

7

如OM-NOM-NOM指出,要注意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溶液。

注:breakOut借力CanBuildFrom和助洗劑是重新設計的集合庫Scala中引入的基礎的一部分2.8.0

+0

尼斯之一!從未以這種方式考慮過'breakOut'。 –

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

你好,Luigi,你可以給你一個簡短的解釋代碼嗎?謝謝 – Dzhu

+1

希望我想到了這個。 @Dzhu它只是使用'foldLeft'('/:'只是該方法的簡稱),它接受一個初始值,然後將一個運算符應用於從左到右的每個序列值。在這種情況下,序列就是字符串,而運算符只是將字符串的字符添加到結果中。 –

+0

@Dzhu''「/:s'是一種以中綴表示方式調用的方法。由於'/:'方法以':'結尾,因此調用'''''參數'''''''。如果你在Scala文檔中查找String,你將不會找到它,因爲它只是Java類,但是你會發現'StringOps'被隱式轉換成了String,在這裏你會找到'/:'方法。它是curried的並且有第二個參數,它是(這裏)是一個類型爲'(String,Char)=> String'的匿名函數。另見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