Extract Element and its Followers from List I wrote the following function to convert List[Int] =&gt; List[List[Int]].

Its intended purpose is to extract 1, followed by its non 1 followers, into a group.

input: List(1,2,2,1,3,3) 

output: List( List(1,2,2), List(1,3,3) )

Function

def leadingOnesGroup(xs: List[Int]): List[List[Int]] = 
        xs match {
          case Nil    =&gt; Nil 
          case _ :: _ =&gt; 
           val (first, rest)          = xs.span(_ == 1)
           val (followers, remainder) = rest.span(_ != 1)
           (first ++ followers) :: leadingOnesGroup(remainder)
      }


Testing

scala&gt; leadingOnesGroup(List(1,2,2))
res19: List[List[Int]] = List(List(1, 2, 2))

scala&gt; leadingOnesGroup(List(1,2,2,1,3,3))
res20: List[List[Int]] = List(List(1, 2, 2), List(1, 3, 3))

scala&gt; leadingOnesGroup(List(1,2,2,1,3,3,1,5,5))
res21: List[List[Int]] = List(List(1, 2, 2), List(1, 3, 3), List(1, 5, 5))
The current version of the function does not take into account the cases:


(as @itsbruce mentioned) if the list starts with a value other than '1'
if there are consecutive '1's


The second case is using wildcards, but instead it'd better directly match a list starting with '1':

case 1 :: tail =&gt; {
  // we take only the following elements different from 1
  val followers = tail.takeWhile(_ != 1)
  // we drop the 'followers' prefix for the recursive call
  val remainder = tail.drop(followers.size)
  (1 :: followers) :: leadingOnesGroup(remainder)
}


Of course, this block can be shortened to two lines only, but it will be less readable.

Since it is not clear how to process lists that do not start with '1', a generic matcher with an explicit exception can be added:

case _ =&gt; throw new IllegalArgumentException("Unexpected start of list: " + xs)