## 1. Introduction

Scala allows us to split a sequence by a predicate in several different ways. This means taking a single sequence and applying some filtering logic to it to end up with two sequences. In this tutorial we’ll explore the most common ways to do this by going through a simple example.

## 2. Using *partition*

The *partition* method belongs to the *TraversableLike* trait. We’ll use it to run a predicate against each element of a sequence and return to us two sequences. **O****ne sequence contains elements that satisfy the predicate, and the other sequence contains elements that don’t satisfy it**. Remember, a predicate is a function that returns a *Boolean*.

Let’s say we have a sequence of integers:

```
val intSequence: Seq[Int] = Seq(1,2,3,4,5,6)
intSequence: List(1, 2, 3, 4, 5, 6)
```

We’ll use *partition* to split this sequence into a sequence of even integers and odd integers:

```
val (even, odd) = intSequence.partition(_ % 2 == 0)
even: List(2, 4, 6)
odd: List(1, 3, 5)
```

We’ve applied a predicate that checks if the modulus of each element in the sequence equals 0. Two new sequences will be returned from this operation, which we destructure into *even *and *odd* variables.

As we can see, the result is a sequence of even numbers and a sequence of odd numbers.

## 3. Using *span*

The *span* method also allows us to split a sequence into two sequences. However, it works very differently from *partition*: *span *puts all elements in one sequence until an element is false, and from that point forward it will put all remaining sequence in the second list.

In this next example, we want the first half of the numbers to be in the first sequence and the second half of the numbers to be in the second sequence:

```
val intSequence: Seq[Int] = Seq(1,2,3,4,5,6)
val (firstHalf, secondHalf) = intSequence.span(_ <= intSequence.length / 2)
firstHalf: List(1, 2, 3)
secondHalf: List(4, 5, 6)
```

The remaining elements are put into the second sequence as soon as the predicate is *false*.

## 4. Using *groupBy*

The *groupBy* method works very similarly to *partition* in the sense that it takes a predicate function as its parameter. The difference is the output: *groupBy* groups elements by key and their associated values into a *Map*** collection**.

Let’s look at the first example with odd and even integers again:

```
val intSequence: Seq[Int] = Seq(1,2,3,4,5,6)
intSequence: List(1, 2, 3, 4, 5, 6)
```

We’ll use *groupBy* and supply the same predicate to check for even numbers:

```
val res = intSequence.groupBy(_ % 2 == 0)
res: HashMap(false -> List(1, 3, 5), true -> List(2, 4, 6))
```

The result is a *HashMap* that contains two key-value pairs: a *false* key with a value that contains a sequence of all the elements which don’t satisfy the predicate (odd numbers) and a *true* key with a value that contains a sequence of even elements.

**The groupBy method is especially useful if we think we’ll need to change the condition into something that isn’t a Boolean in the future.**

## 5. Conclusion

As demonstrated in this article, there are several different ways to split sequences in Scala, and the one we’ll choose depends on the problem we’re trying to solve:

*partition*is useful when we’re simply splitting a sequence based on the result of a boolean predicate.*span*is preferable when we want to put all elements in a second sequence once an element returns*false*against the predicate.*groupBy*is similar to*partition*but allows us to future-proof our code in case the condition isn’t a*Boolean*in the future.