Dark theme | Light theme

December 16, 2022

Kotlin Kandy: Create Fix Sized Sublists From Iterables With chunked

The chunked extension method is added to the Iterable Java class and makes it possible to split an iterable into fixed sized lists. We define the size of the lists as argument to the chunked method. The return result is a list of lists. Each of the lists will have the number of elements we have specified as argument. The last list can have less elements if the total number of elements cannot be divided exactly by the size we specified as argument. We can specify a lambda transformation function as second argument. The lambda function has the new sublist as argument and we can write code to transform that sublist.

In the following example we use the chunked method with different arguments and see what the results look like:

// Sample list of letters.
val letters = listOf('a', 'B', 'c', 'D', 'e', 'F', 'g')

// With chunked we specify the number of items
// that should be grouped together into a new list.
// The return type is a List of List instances.
assert(letters.chunked(3) == listOf(
    listOf('a', 'B', 'c'),
    listOf('D', 'e', 'F'),

assert(letters.chunked(4) == listOf(
    listOf('a', 'B', 'c', 'D'),
    listOf('e', 'F', 'g')))

// If the number of items left is less than the given
// size it is a "remainder".
// In the following helper function we can include or
// exclude the remainder List.
fun chunckedRemainder(chars: List<Char> , size: Int, remainder: Boolean) =
    if (remainder) chars.chunked(size)
    else chars.chunked(size).filter { it.size == size }

// We can skip the remainder in the end result.
assert(chunckedRemainder(letters, 4, false) == listOf(
    listOf('a', 'B', 'c', 'D')))

assert(chunckedRemainder(letters, 4, true) == listOf(
    listOf('a', 'B', 'c', 'D'),
    listOf('e', 'F', 'g')))

// We can use a second argument and provide a transformation
// lambda function to transform the lists that are returned
// from chunking the original collection.
val chunkedJoined = letters.chunked(3) { list -> list.joinToString(separator = "") }

assert(chunkedJoined == listOf("aBc", "DeF", "g"))

Written with Kotlin 1.7.21.