Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: April 10, 2025
In this tutorial, we’re going to explore how to split a list into sub-lists of the same size. For example, given a list of characters List(‘b’, ‘a’, ‘e’, ‘l’, ‘d’, ‘u’, ‘n’, ‘g’), and a destination size of 3, we’d obtain the list List(List(‘b’, ‘a’, ‘e’), List(‘l’, ‘d’, ‘u’), List(‘n’, ‘g’)).
The input to this algorithm has two inputs:
The original list will be split into lists, each of them being of the size specified in the second parameter. Attention must be paid to the following points:
We can easily implement a recursive method to do the split:
@throws[IllegalArgumentException]("if the slice size is less than one")
private def recursiveSplit[A](list: List[A], n: Int): List[List[A]] =
if (n < 1)
throw new IllegalArgumentException("The minimum slice size is one")
else {
if (list.isEmpty) List.empty[List[A]]
else list.take(n) :: recursiveSplit(list.drop(n), n)
}
Note that the method takes a type parameter, because we want it to work on lists with elements of any type. The method is a simple recursive function.
Let’s also add a wrapper method to cater to the expected Try monad:
def split[A](list: List[A], n: Int): Try[List[List[A]]] =
Try(recursiveSplit(list, n))
Even more efficient is to use the native collections library that Scala provides out of the box. For example, in our case, we can traverse the list using the sliding() method, then transform the returned iterator to a list:
@throws[IllegalArgumentException]("if the slice size is less than one")
private def splitUsingSliding[A](list: List[A], n: Int): List[List[A]] =
if (n < 1)
throw new IllegalArgumentException("The minimum slice size is one")
else list.sliding(n, n).toList
Lets test the considerations expressed in section 2. If we split a list of, say, 105 elements, into lists of 10, we should get 11 lists:
"ListSplitter" should {
"return a list of the right number of lists" in {
val originalList = (0 until 105).toList
val splitListTry = ListSplitter.split(originalList, 10)
assert(splitListTry.isSuccess)
val splitList = splitListTry.get
assertResult(11)(splitList.size)
}
...
If we split our list of 105 elements into lists of size 10, and then reassemble them, we should get a new list of 105 elements:
...
"return a list of lists with the right cumulative number of elements" in {
val originalList = (0 until 105).toList
val splitListTry = ListSplitter.split(originalList, 10)
assert(splitListTry.isSuccess)
val splitList = splitListTry.get
val count = splitList.foldLeft(0)((n, bs) => n + bs.size)
assertResult(105)(count)
}
...
Let’s try with a list of chars. This is the original example used in the introduction:
...
"return a list of lists with the right elements and the right order" in {
val baeldung = List('b', 'a', 'e', 'l', 'd', 'u', 'n', 'g')
val splitBaeldungTry = ListSplitter.split(baeldung, 3)
assert(splitBaeldungTry.isSuccess)
val splitBaeldung = splitBaeldungTry.get
val expected =
List(List('b', 'a', 'e'), List('l', 'd', 'u'), List('n', 'g'))
assertResult(expected)(splitBaeldung)
}
...
In terms of efficiency and development time, using the available Scala libraries is recommended. However, sometimes exploring ways to implement solutions to specific small problems is a good way to hone our programming skills.