Hacking with Kotlin: ranges

As you may know, C# 8 introduces bounded ranges.

The syntax looks like this:

var array = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
var subarray = array[3..5]; // The selected items: 3, 4

Can we achieve the same with Kotlin?

Of course we can!

We’ll start with a list:

val list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

But there’s nicer syntax for that already:

val list = (0..10).toList()

And there’s already function available:

println(list.subList(3, 5)) // [3, 4]

Let’s first make it work with the following syntax:

println(list.subList(3..5)) // Doesn't compile yet

For that we’ll use extension function that accepts range of integers:

fun <E> List<E>.subList(range: ClosedRange<Int>): List<E> {
return this.subList(range.start, range.endInclusive)

As you can see, is just a that has and members

Now the following code should work:

println(list.subList(3..5)) // [3, 4]

Next we want the following nice syntax to work too:

println(list[3..5]) // Doesn't compile yet

For that we’ll have another extension function:

operator fun <E> List<E>.get(range: ClosedRange<Int>): List<E> {
return this.subList(range)

Since square brackets are special symbols, we mark this function as to be able to use them.

And we simply delegate the logic to the first function we had written.

We can also make it even shorter:

operator fun <E> List<E>.get(range: ClosedRange<Int>) = this.subList(range)

And now, we’re in C# 8 land:

println(list[3..5]) // [3, 4]

No need to wait for the next major version of your favorite language.

Happy Kotlin, and stay tuned for next post in series!

Solutions Architect @Depop, author of “Hands-on Design Patterns with Kotlin” book and “Web Development with Kotlin” course