2013-06-07 10 views
11

"A"、 "B"、 "C"のように3つの文字列があります。 それらを連結した結果の文字列を生成する必要があります.2番目の文字列だけを空白で所定の長さにパディングする必要があります。埋め込まれた文字列を連結する

val s1 = "A" 
val s2 = "B" 
val s3 = "C" 
val padLength = 20 

val s = s1 + s2.padTo(padLength, " ") + s3 

padToは、その内部のtoString文字列が、ベクトルのような表現を返さないSeqLikeを返すので、間違っている:

これは直感と一般的なスカラ座newbinessによって導かれたとして私の最初の試みでした。

Scalaでこれを行うには、どのような慣用方法が最適でしょうか?

+0

+1直感+初心者用。 –

答えて

19

String文字のコレクションのように考えられて(ここではStringOpsへの暗黙的な変換を経由して)することができ、ので、あなたのパディングする必要があります:あなたが終わるので、String.padTo(padLength, " ")を呼び出す

val s = s1 + s2.padTo(padLength, ' ') + s3 // note the single quotes: a char 

が実際にSeq[Any]を返します。あなたの順序で文字と文字列の両方を使用します。

2

これは動作します:

val s = s1 + s2.padTo(padLength, " ").mkString + s3 

を何とかグラグラ感じています。

+0

より良い製剤:b.padTo(10、 "「).mkString(、 ""、C)SOM-snytt @ –

+0

はいはいはい、slapface時間。 –

8

あなたは左か右にパッドしたいかどうかは言っていません。

val s = f"$s1%s$s2%20s$s3" 

あるいは、Scalaの2.10の前に(あるいはあなたがパラメータとして「20」を必要とする場合)::ただの形式を使用

val s = "%s%"+padLength+"s%s" format (s1, s2, s3) 

利用代わりに左の右にパディングスペースを追加するために、負のパディング。

+1

upvoteをやっていない人のために、http://scalapuzzlers.com/#pzzlr-027、愚かな小さなパッディングルーチンをカスタマイズすることの危険に対するプラグは、https://github.com/scala/scala /blob/master/src/compiler/scala/tools/nsc/Global.scala#L751。説明は –

1
s1 + s2 + " "*(padLength - s2.size) + s3 
2

利用可能な方法はformattedです。

val s = s1 + s2.formatted("%-10s") + s3 

などformat:たとえば

val s = s1 + "%-10s".format(s2) + s3 

しかしpadLengthを直接埋め込むことができる場合、私は、それを使用します。

他の場所で定義されている場合(例のように)、gourlaysamaが指摘したようにpadToを使用できます。

あなたは「パッドは左」、あなたは暗黙のクラスを使用することができますしたい場合:

object Container { 
    implicit class RichChar(c: Char) { 
    def repeat(n: Int): String = "".padTo(n, c) 
    } 

    implicit class RichString(s: String) { 
    def padRight(n: Int): String = { 
     s + ' '.repeat(n - s.length) 
    } 

    def padLeft(n: Int): String = { 
     ' '.repeat(n - s.length) + s 
    } 
    } 
} 

object StringFormat1Example extends App { 
    val s = "Hello" 

    import Container._ 

    println(s.padLeft(10)) 
    println(s.padRight(10)) 
} 
5

誰かがあなたが警告を上げる必要があることを言及する必要があります:間違って何もないことを

[email protected]:~$ skala -Ywarn-infer-any 
Welcome to Scala version 2.11.0-20130524-174214-08a368770c (OpenJDK 64-Bit Server VM, Java 1.7.0_21). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> "abc".padTo(10, "*").mkString 
<console>:7: warning: a type was inferred to be `Any`; this may indicate a programming error. 
     val res0 = 
     ^
res0: String = abc******* 

注意(それをこのようにして)。これはあなたのユースケースではありませんので、あなたが冗長であるAPIを使用したい場合は、多分あなたが尋ねるべきで、

scala> case class Ikon(c: Char) { override def toString = c.toString } 
defined class Ikon 

scala> List(Ikon('#'),Ikon('@'),Ikon('!')).padTo(10, "*").mkString 
res1: String = #@!******* 

またはより良い

scala> case class Result(i: Int) { override def toString = f"$i%03d" } 
defined class Result 

scala> List(Result(23),Result(666)).padTo(10, "---").mkString 
res4: String = 023666------------------------ 

は多分のためのユースケースがあります危険を伴います。ダニエルの答えが正しいものである理由です

。彼の例の書式文字列がなぜ怖いのかは分かりませんが、読みやすい文字列ではいくつかの場所で文字の書式設定が必要なだけなので、通常はより良性に見えます。

scala> val a,b,c = "xyz" 

scala> f"$a is followed by `$b%10s` and $c%.1s remaining" 
res6: String = xyz is followed by `  xyz` and x remaining 

あなたが偽のフォーマッタを追加するために必要なている一つのケースでは、改行したいときです:

scala> f"$a%s%n$b$c" 
res8: String = 
xyz 
xyzxyz 

を私は補間をfを処理すべきだと思う「の%n $ bを$」。ああ、それは2.11で修正されています。

scala> f"$a%n$b" // old 
<console>:10: error: illegal conversion character 
       f"$a%n$b" 

scala> f"$a%n$b" // new 
res9: String = 
xyz 
xyz 

ここで、実際には補間しない理由はありません。

+0

+1です。ダニエルの答えについて嫌いなのは、補間された文字列が.padToオプションより読みにくいということです。 –

1

これは、その他の再定式化に追加する価値がある:保存し

scala> val a = "A"; val b="B";val c="C" 
a: String = A 
b: String = B 
c: String = C 

scala> b.padTo(10, " ").mkString(a, "", c) 
res1: String = AB   C 

日曜日に教会のためにいくつかの+さん。

私はthis really wonky commitでmkStringを悪用で信者になりました。

関連する問題