2016-12-02 97 views
1

誰能解釋一下:如何分割在子列表,其中一個列表:斯卡拉:分割清單到子表

列表:

scala> val ls = List("P ", "PP ", "PP ", "PP ", "P ", "PP ", "PP ", "P ") 

或者

scala> val ls = List("P", "PP", "PP", "PP", "P", "PP", "PP", "P") 

子列表:

List("P", "PP", "PP", "PP"), List("P", "PP", "PP"), List("P") 


EDITED ::我真正想要的是在特定字符串的每一個出現處分割列表!

TIA。

+1

什麼邏輯這裏?當長度減少時拆分? – Marth

+0

您需要編碼列表。有一個邏輯。將長度更改爲一個列表中的所有項目之後等等。 – Pavel

+0

您是否嘗試過檢查這裏是否有東西?你可以使用:http://www.scala-lang.org/api/current/scala/collection/immutable/List.html看看takeWhile,partiion,slice方法。 – Pavel

回答

1
List("P ", "PP ", "PP ", "PP ", "P ", "PP ", "PP ", "P ") 
    .scanLeft((0, Option.empty[String])) { 
    case ((count, _), "P ") ⇒ (count + 1, Some("P ")) 
    case ((count, _), s) ⇒ (count, Some(s)) 
    }.groupBy(_._1) 
    .mapValues(_.collect { case (cnt, Some(x)) ⇒ x }) 
    .toList.sortBy(_._1).map(_._2) 
2

遞歸(但不是尾遞歸)溶液:

val l = List("P ", "PP ", "PP ", "PP ", "P ", "PP ", "PP ", "P ") 

def splitBy(l: List[String], s: String): List[List[String]] = { 
    l.splitAt(l.lastIndexOf(s)) match { 
    case (Nil, tail) => List(tail) 
    case (head, tail) => splitBy(head, s) :+ tail 
    } 
} 

splitBy(l, "P ") // List(List(P , PP , PP , PP), List(P , PP , PP), List(P)) 

尾遞歸版本:

val l = List("P", "PP", "PP", "PP", "P", "PP", "PP", "P") 

def splitBy(result: List[List[String]], l: List[String], s: String): List[List[String]] = { 
    l.splitAt(l.lastIndexOf(s)) match { 
    case (Nil, y) => List(y) ::: result 
    case (x, y) => splitBy(List(y) ::: result, x, s) 
    } 
} 

println(splitBy(Nil, l, "P")) 
4

使用foldLeft另一種選擇:

l.foldLeft(List[List[String]]()) { 
    case (Nil, s) => List(List(s)) 
    case (result, "P ") => result :+ List("P ") 
    case (result, s) => result.dropRight(1) :+ (result.last :+ s) 
}