How to split a sequence into two pieces by predicate?

By using partition method:

scala> List(1,2,3,4).partition(x => x % 2 == 0)
res0: (List[Int], List[Int]) = (List(2, 4),List(1, 3))

Good that partition was the thing you wanted -- there's another method that also uses a predicate to split a list in two: span.

The first one, partition will put all "true" elements in one list, and the others in the second list.

span will put all elements in one list until an element is "false" (in terms of the predicate). From that point forward, it will put the elements in the second list.

scala> Seq(1,2,3,4).span(x => x % 2 == 0)
res0: (Seq[Int], Seq[Int]) = (List(),List(1, 2, 3, 4))

You can also use foldLeft if you need something a little extra. I just wrote some code like this when partition didn't cut it:

val list:List[Person] = /* get your list */
val (students,teachers) = 
  list.foldLeft(List.empty[Student],List.empty[Teacher]) {
    case ((acc1, acc2), p) => p match {
      case s:Student => (s :: acc1, acc2)
      case t:Teacher  => (acc1, t :: acc2)
    }
  }

You might want to take a look at scalex.org - it allows you to search the scala standard library for functions by their signature. For example, type the following:

List[A] => (A => Boolean) => (List[A], List[A])

You would see partition.

Tags:

Scala