scala - 多行字符串拆分

时间:2014-11-25 08:47:31

标签: string scala

我有这个:

val msg = "Preparado para cocinar..."
val message = msg.splitAt(msg.length()/2)

println(message._1 + "\n" + message._2.trim())

问题是我得到了这个结果(bcz我只是把它分成中间):

Preparado pa
ra cocinar...

我如何显示多个(不仅仅是2部分)显示的消息,但它应该在spaces中分开而不是在句子的中间?

3 个答案:

答案 0 :(得分:2)

一个不太优雅的工作解决方案,

val a = msg.split("\\s")  // Split by space
a = Array(Preparado, para, cocinar...)

val n = a.size / 2  // Get halving point rounded to lower closest integer
n = 1

val b = Array(a.take(n).mkString, a.drop(n).mkString(" "))  // Halve the array
b = Array(Preparado, para cocinar...)

b.foreach(println)  // Print it
Preparado
para cocinar...

<强>更新

正如@AdrienAubel指出的那样,考虑在{em> split 数组上使用splitAt

val (b1,b2) = a.splitAt(n)
b1 = Array(Preparado)
b2 = Array(para, cocinar...)

println(b1.mkString(" "))
Preparado

println(b2.mkString(" "))
para cocinar...

答案 1 :(得分:2)

一个相当优雅的功能解决方案

def wordWrap(s: String, n: Int) = s.split("\\s").foldLeft(List[String]())
     { (lines, word) =>
        if (lines.isEmpty || lines.head.length + word.length + 1 > n)
          word :: lines
       else
         (lines.head + " " + word) :: lines.tail
     }
    .reverse

wordWrap( "Preparado para cocinar...", 23)
// List(Preparado para, cocinar...)
wordWrap( "Preparado para cocinar...", 5)
// List(Preparado, para, cocinar...)
wordWrap("A quick brown fox jumps over the lazy dog.", 10)
// List(A quick, brown fox, jumps over, the lazy, dog. )

只检查一次空列表的变体

def wordWrap(s: String, n: Int) = {
    val words = s.split("\\s")
    if (words.isEmpty) Nil
    else
      words.tail.foldLeft(List[String](words.head)){ (lines, word) =>
         if (lines.head.length + word.length + 1 > n) 
           word :: lines
         else
          (lines.head + " " + word) :: lines.tail
      }.reverse
  }

答案 2 :(得分:1)

另一个非常不优雅的功能解决方案。

我非常肯定会有更好的想法来实现。

代码

def divide(msg: String): (String, String) = {

  //index each letter
  val indexed = msg.zipWithIndex

  //split at first blank space after midpoint    
  val (fst, snd) = indexed span {case (c, i) => i < indexed.size/2 || c != ' '}

  //utility to recompose indexed parts
  def unzipString(s: Seq[(Char, Int)]) = s.map(_._1).mkString.trim

  //get separated lines    
  (unzipString(fst), unzipString(snd))
}

REPL

scala> val msg = "Parando para cocinar..."
msg: String = Parando para cocinar...

scala> val indexed = msg.zipWithIndex
indexed: scala.collection.immutable.IndexedSeq[(Char, Int)] = Vector((P,0), (a,1), (r,2), (a,3), (n,4), (d,5), (o,6), ( ,7), (p,8), (a,9), (r,10), (a,11), ( ,
12), (c,13), (o,14), (c,15), (i,16), (n,17), (a,18), (r,19), (.,20), (.,21), (.,22))

scala> val (fst, snd) = indexed span {case (c, i) => i < indexed.size/2 || c != ' '}
fst: scala.collection.immutable.IndexedSeq[(Char, Int)] = Vector((P,0), (a,1), (r,2), (a,3), (n,4), (d,5), (o,6), ( ,7), (p,8), (a,9), (r,10), (a,11))
snd: scala.collection.immutable.IndexedSeq[(Char, Int)] = Vector(( ,12), (c,13), (o,14), (c,15), (i,16), (n,17), (a,18), (r,19), (.,20), (.,21), (.,22))

scala> def unzipString(s: Seq[(Char, Int)]): String = s.map(_._1).mkString.trim
unzipString: (s: Seq[(Char, Int)])String

scala> (unzipString(fst), unzipString(snd))
res2: (String, String) = (Parando para,cocinar...)

更新:原始答案有几个明显的错误