Partition a List into sublists of given size in Kotlin
This article explores different ways to partition a list into sublists of a given size in Kotlin. The last list in the resulting collection may contain fewer elements.
1. Using chunked() function
With Kotlin 1.2, we can use the chunked() function to split a list into a list of lists, each not exceeding the given size. It can be used as follows:
|
1 2 3 4 5 6 7 |
fun main() { val collection = (1.. 15).toList() val chunkSize = 4 val partitions: List<List<Int>> = collection.chunked(chunkSize) println(partitions) } |
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
2. Using windowed() function
Alternatively, we can use the windowed() library function starting with Kotlin 1.2. A typical invocation for this function would look like:
|
1 2 3 4 5 6 7 |
fun main() { val collection = (1.. 15).toList() val chunkSize = 4 val partitions: List<List<Int>> = collection.windowed(size = chunkSize, step = chunkSize, partialWindows = true) println(partitions) } |
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
3. Using subList() function
Before Kotlin 1.2, we can write custom logic to partition a list into equal-size chunks. The following solution uses a loop to iterate over the list and the subList() function to partition the list between starting and ending index.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
fun main() { val collection = (1.. 15).toList() val chunkSize = 4 val partitions: MutableList<List<Int>> = mutableListOf() var i = 0 while (i < collection.size) { partitions.add(collection.subList(i, (i + chunkSize).coerceAtMost(collection.size))) i += chunkSize } println(partitions) } |
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
This is equivalent to the following code using the map() function:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
fun <T> partition(collection: List<T>, chunkSize: Int): List<List<T>> { return (0.. (collection.size - 1) / chunkSize) .map { collection.subList( it * chunkSize, ((it + 1) * chunkSize).coerceAtMost(collection.size) )} } fun main() { val collection = (1.. 15).toList() val chunkSize = 4 val partitions = partition(collection, chunkSize) println(partitions) } |
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
4. Using groupBy() function
Another option is to use the groupBy() function to perform the equivalent of a “group by” operation on the list elements. It groups the elements according to a classification function and returns the results in a map.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fun <T> partition(collection: List<T>, chunkSize: Int): Collection<List<T>> { return collection.withIndex(). groupBy { it.index / chunkSize }. map { it.value.map { it.value } } } fun main() { val collection = (1.. 15).toList() val chunkSize = 4 val partitions = partition(collection, chunkSize) println(partitions) } |
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
The code can be simplified using a mutable counter like AtomicInteger:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import java.util.concurrent.atomic.AtomicInteger fun <T> partition(collection: List<T>, n: Int): Collection<List<T>> { val counter = AtomicInteger() return collection.groupBy { counter.getAndIncrement() / n }.values } fun main() { val collection = (1.. 15).toList() val chunkSize = 4 val partitions = partition(collection, chunkSize) println(partitions) } |
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
That’s all about partitioning a list into sublists of a given size in Kotlin.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)