title: Scala: splitting a list using a predicate for sublists
body: <p>I just had a use case where I needed to split a list into n sublists, so that elements are taken in order from the original list and grouped while the predicate is true for the sublist (when it is false, a new sublist is started). I didn't find this functionality in the standard library, and I thought it was a good exercise to try to solve it in a functional style (as I'm far from a functional guru). </p>
  
  <p>Below is the code I came up with. But I suspect it can be improved a lot. Can you help me find a better way to code this? </p>
  
  <pre><code>class ListWithSplitter[A](val theList:List[A])
  {
    private def sublistWhile(list:List[A], pred:(List[A] =&gt; Boolean)):(List[A],List[A]) =
    {
      def combine(okList:List[A], remaining:List[A], pred:(List[A] =&gt; Boolean)):(List[A],List[A]) =
      {
        if(pred(okList ::: remaining.head :: Nil))
          combine(okList ::: remaining.head :: Nil, remaining.tail, pred)
        else
          (okList, remaining)
      }
  
      list match {
        case Nil =&gt; (Nil, Nil)
        case x :: Nil =&gt; (list, Nil)
        case x :: xs =&gt; combine(List(x), xs, pred)
      }
    }
  
    private def combinedSplit(list:List[A], pred:(List[A] =&gt; Boolean)):List[List[A]] =
    {
      val r = sublistWhile(list, pred)
      r match {
        case (Nil, Nil) =&gt; List(Nil)
        case (x, Nil) =&gt; List(x)
        case (x, y) =&gt; x :: combinedSplit(y, pred)
      }
    }
  
    def combinedSplit(pred:(List[A] =&gt; Boolean)):List[List[A]] =
    {
      combinedSplit(theList, pred)
    }
  }
  
  trait ListCombinedSplit
  {
    implicit def list2combSplitter[A](x:List[A]) : ListWithSplitter[A] = new ListWithSplitter(x)
  }
  
  object ListSplitter extends ListCombinedSplit {
  
    def main(args:Array[String])
    {
      // sample usage: sum of each sublist is less than 100
      val a = List(4, 59, 10, 24, 42, 9, 2, 44, 44, 44, 44)
      val b = a combinedSplit { list:List[Int] =&gt; ((0 /: list)(_ + _)) &lt; 100 }
  
      b foreach println
    }
  }
  </code></pre>
  
  <p>Result of sample is:</p>
  
  <pre><code>List(4, 59, 10, 24)
  List(42, 9, 2, 44)
  List(44, 44)
  List(44)
  </code></pre>