I have a list like this:
val data = List("a","b","","c","d","e","","a","b","c")
I want to split it from the elements "":
List(List("a","b"),List("c","d","e"),List("a","b","c"))
What would be the Scala way?
something like:
data.MAGIC(_=="")
I have a list like this:
val data = List("a","b","","c","d","e","","a","b","c")
I want to split it from the elements "":
List(List("a","b"),List("c","d","e"),List("a","b","c"))
What would be the Scala way?
something like:
data.MAGIC(_=="")
Using span
:
def magic[T](l: List[T]): List[List[T]] = {
@tailrec
def magicAux[T](l: List[T], r: MutableList[List[T]]): MutableList[List[T]] = {
val (p, s) = l.span(_ != "")
s match {
case Nil => r += p
case _ => magicAux(s.tail, r += p)
}
}
magicAux(l, new MutableList[List[T]]()).toList
}
How about this one:
scala> Stream.iterate(""::data){ _.tail.dropWhile(_.nonEmpty) }
.takeWhile(_.nonEmpty)
.map{ _.tail.takeWhile(_.nonEmpty) }.toList
res1: List[List[String]] = List(List(a, b), List(c, d, e), List(a, b, c))
Or this one:
scala> (-1 +: data.zipWithIndex.collect{ case ("", i) => i } :+ data.size)
.sliding(2).toList
.map{ case List(h, t) => data.slice(h+1,t) }
res2: List[List[String]] = List(List(a, b), List(c, d, e), List(a, b, c))
And this one:
scala> (data:+"").foldLeft(List[List[String]](), List[String]()){
case((xs, x), v) => if(v.isEmpty) (x.reverse::xs, Nil) else (xs,v::x)
}._1.reverse
res3: List[List[String]] = List(List(a, b), List(c, d, e), List(a, b, c))
Using foldRight
:
val res = ("" :: data).foldRight(List[List[_]](Nil))((x, s) =>
(x, s) match {
case ("", Nil :: _) => s
case ("", _) => Nil :: s
case (x, h :: t) => (x :: h) :: t
}).tail