Collection processing in Kotlin: drop and take
This is a chapter from the book Functional Kotlin. You can find it on LeanPub or Amazon. It is also available as a course.
When you need to take or get rid of a certain number of elements, the take
, takeLast
, drop
and dropLast
functions are at your service:
take(n)
- returns a collection with only the firstn
elements (or returns the unchanged collection if it has less thann
elements).takeLast(n)
- returns a collection with only the lastn
elements (or returns the unchanged collection if it has less thann
elements).drop(n)
- returns a collection without the firstn
elements.dropLast(n)
- returns a collection without the lastn
elements.
Kotlin by design doesn't have aliases for
head
(to take the first element) ortail
(to drop the first element) methods, that are well known in other functional languages. Instead, we usefirst()
anddrop(1)
.
Most collection processing functions, including take
and drop
, are extension functions on the Iterable
interface, but takeLast
and dropLast
are extension functions on List
. Such design is needed for efficiency.
If we know the size of our collection, these methods can be used interchangeably:
l.take(n)
gives the same result asl.dropLast(l.size - n)
,l.takeLast(n)
gives the same result asl.drop(l.size - n)
,l.drop(n)
gives the same result asl.takeLast(l.size - n)
,l.dropLast(n)
gives the same result asl.take(l.size - n)
,
If we are operating on a List
, all these methods can be replaced with the more universal subList
, which expects as arguments the start index (inclusive) and the end index (exclusive), so:
l.take(n)
gives the same result asl.subList(0, n)
,l.takeLast(n)
gives the same result asl.subList(l.size - n, l.size)
,l.drop(n)
gives the same result asl.subList(n, l.size)
,l.dropLast(n)
gives the same result asl.subList(0, l.size - n)
,
I find take
, takeLast
, drop
and dropLast
much more readable than subList
, which requires unintuitive operations on indexes. They are also safer - when we ask to drop more elements than there are in the collection, the result is an empty collection, when we try to take more than there is the result is the collection with as many elements as possible, when we call subList
with an incorrect value, it throws an exception.