2

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(_=="")
Omid
  • 1,959
  • 25
  • 42

3 Answers3

3

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
}  
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • Thanks Jean, but I'm searching for some kind of collection way, do you think is there any "nicer" way – Omid Jan 05 '15 at 03:47
  • @Omid If by "nicer" you mean something in the standard library, there isn't anything that does this. And if there were, it would be a method that looks something like this. – Michael Zajac Jan 05 '15 at 23:59
1

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))
Eastsun
  • 18,526
  • 6
  • 57
  • 81
0

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
user5102379
  • 1,492
  • 9
  • 9