2011-10-08 10 views
7

私はただ与えられた文字列を逆にする簡単な関数を書いて、スカラ座への初心者だ:Scalaの逆文字列

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 1つの少ない値にNE)あなたは負のステップを指定する必要があります。または、空のセットを取得します:OM-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

om-nom-nomに感謝します。私はそれを自分で実装したいので、私は学ぶことができます:) – Dzhu

7

を、そうでない場合は、あなたが本当に反復処理し、あなたの結果されていません(by -1に注意を払います空になります)。あなたが使用できる他のトリックはcollection.breakOutです。 breakOutを使用する利点は、それがmkString溶液のような中間構造を作成しないことである

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

reverse("foo") 
// String = oof 

また、このようなfor理解に提供することができます。

注:breakOutは2.8.0

+0

いいです!その方法で 'breakOut'を考えたことはありません。 –

8

ます。また、これは(再帰的なアプローチを使用してだけでは、このいずれかを投げて書くことができCanBuildFromとScalaで導入された再設計されたコレクション・ライブラリーの基盤の一部であるビルダーを活用しています楽しみのために)

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) 
01です

編集 :またはさらに短い、我々は素晴らしく不可解

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

を持っているが、私は本当にこのことをお勧めしません...

+2

こんにちはルイージ、あなたのコードの簡単な説明を教えてください。ありがとう – Dzhu

+1

私はこれを考えました。 @Dzhuちょうど 'foldLeft'(' /: 'はそのメソッドの単なる名前です)を使用しています。これは初期値をとり、左から順にシーケンスの各値に演算子を適用します。この場合、シーケンスは文字列であり、演算子は文字列の文字を結果の前に付加するだけです。 –

+0

@Dzhu '" "" /:s'は中置表記のメソッド呼び出しです。メソッド '/:'は ':'で終わるので、 '' ''で 's'を呼び出しています。 Scalaのドキュメントで文字列を検索すると、それはJavaクラスなので見つからないでしょうが、文字列が暗黙的に変換される 'StringOps'が見つかります。ここで' /: 'メソッドを見つけることができます。それはカリーされ、 '(String、Char)=> String'型の無名関数(ここでは)である2番目の引数をとります。 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 
関連する問題