def splitBySeparator[T](l: List[T], sep: T): List[List[T]] = {
l.span( _ != sep ) match {
case (hd, _ :: tl) => hd :: splitBySeparator(tl, sep)
case (hd, _) => List(hd)
}
}
val items = List("Apple","Banana","Orange","Tomato","Grapes","BREAK","Salt","Pepper","BREAK","Fish","Chicken","Beef")
splitBySeparator(items, "BREAK")
Result:
res1: List[List[String]] = List(List(Apple, Banana, Orange, Tomato, Grapes), List(Salt, Pepper), List(Fish, Chicken, Beef))
UPDATE: The above version, while concise and effective, has two problems: it does not handle well the edge cases (like List("BREAK")
or List("BREAK", "Apple", "BREAK")
, and is not tail recursive. So here is another (imperative) version that fixes this:
import collection.mutable.ListBuffer
def splitBySeparator[T](l: Seq[T], sep: T): Seq[Seq[T]] = {
val b = ListBuffer(ListBuffer[T]())
l foreach { e =>
if ( e == sep ) {
if ( !b.last.isEmpty ) b += ListBuffer[T]()
}
else b.last += e
}
b.map(_.toSeq)
}
It internally uses a ListBuffer
, much like the implementation of List.span
that I used in the first version of splitBySeparator
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…