Kotlin Explained: Custom Range Expressions

Traversing through dates using Kotlin range expressions

Samuel Urbanowicz
Apr 17, 2019 · 4 min read
Photo by Curtis MacNewton on Unsplash

In order to make the syntax for loop iteration and control flow statements safe and natural to read, Kotlin standard library provides a concept of range. In this post, we are going to explore how to use range expressions in action. First, we are going to discover built-in range implementations for the integral types like Char, Int or Long. Next, we are going to implement a custom progression for the LocalDate class. Let’s get started 🚀!

Iterating through primitive types

The declaration above defines a range of integers of values from 0 to 1000. The rangeTo() function has also its very own operator equivalent .. that allows to declare a range in a more natural way 🦊:

Under the hood, the IntRange implementation contains IntProgressionclass that provides Iterator interface implementation required for iteration. Here is an example of using the progression of integers with the for loop:

As a result of executing the code above we would get the following values printed to the console:

0

100

200

1000

We could also achieve the same result implementing the iteration using while loop in the more imperative manner (but we live in the 21st century and we won’t 😛):

Traversing through non-primitive types

To accomplish this task, first, we need to get familiar with the ClosedRangeand Iterator interfaces. We will need to implement them in order to declare a progression for LocalDate type.

The ClosedRange interface exposes the minimum and maximum values of the range. It also provides contains(value: T): Boolean and isEmpty(): Boolean functions implementation that checks if the given value belongs to the range and if the range is empty. On the other hand, the Iteratorinterface just provides information about the next value and its availability, as follows:

Let’s start with implementing the Iterator instance for the LocalDate type. We are going to create a custom class called DateIterator that implements Iterator<LocalDate> interface.

The DateIterator class has 3 properties:currentDate, endDateInclusiveand stepDays. Inside the next() function, we are returning the currentDate value and updating it to the date value using a given stepDaysproperty interval.

Now, let’s move forward and implement the progression for LocalDate type. We are going to create a new class called DateProgression which is going to implement Iterable<LocalDate> and ClosedRange<LocalDate>interfaces.

The DateProgression class merges functionalities declared by both Iterable<LocalDate> and ClosedRange<LocalDate> interfaces. To allow the iteration we need to provide an instance of DateIterator class as the Iterator value required by Iterable interface. We also need to override start and endInclusive properties of ClosedRange interface directly in the constructor. There is also stepDays property with a default value 1 assigned. As you can see, every time we are invoking the step function, a new instance of DateProgression class is being created.

The last step needed to use LocalDate type in for of range expression is to declare a custom rangeTo operator for the LocalDate class.

That’s it! 🎊Now, we can work with LocalDate type using range expressions. Let’s see how to use our implementation in action. In the example below, we will use our rangeTo operator declaration to iterate through the given dates range:

As a result, the lines of code in the example above would print the next dates with a week-long interval, as follows:

WEDNESDAY 2020–01–01

WEDNESDAY 2020–01–08

WEDNESDAY 2020–12–30

There is more…

Another powerful feature of Kotlin that we have used in the
LocalDate iteration example is operator overloading possibility. It allows to replace functions calls with a concise syntax and helps to write code that is less boilerplate and natural to read at the same time 😀.


Kotlin Explained

Is there something specific you’d like to read in Kotlin Explained series? Write your idea in the comments and stay tuned!


If you’ve found this article useful please show it your love by clicking some claps 👏 on the left-hand side 👈. This way you can let me know my work is important for you. It motivates to write more. And don’t forget to follow kotlin-arsenal publication to be up-to-date. Thanks!

kotlin-arsenal

Top-notch articles and tutorials on Kotlin programming…

Samuel Urbanowicz

Written by

Senior Software Engineer @Netguru. Author of Kotlin Standard Library Cookbook handbook. Planet Earth citizen. Startup soul.

kotlin-arsenal

Top-notch articles and tutorials on Kotlin programming language

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade