Apart from iterations, Kotlin range expressions can be useful when it comes to working with flow control statements. In this recipe, we are going to learn how to use range expressions together with if and when statements in order to tune up the code and make it safe. In this recipe, we are going to consider an example of using the in operator to define a condition of an if statement.
Using range expressions with flow control statements
Getting ready
Kotlin range expressions—represented by the ClosedRange interface—implement a contains(value: T): Boolean function, which returns an information if a given parameter belongs to the range. This feature makes it convenient to use ranges together with control flow instructions. The contains() function has also its equivalent operator, in, and its negation, !in.
How to do it...
- Let's create a variable and assign to it a random integer value:
val randomInt = Random().nextInt()
- Now we can check whether the randomInt value belongs to the scope of integers from 0 to 10 inclusive using range expressions:
if (randomInt in 0..10) {
print("$randomInt belongs to <0, 10> range")
} else {
print("$randomInt doesn't belong to <0, 10> range")
}
How it works...
We have used a range expression together with the in operator in order to define a condition for the if statement. The condition statement is natural to read and concise. In contrast, an equivalent classic implementation would look like this:
val randomInt = Random(20).nextInt()
if (randomInt >= 0 && randomInt <= 10) {
print("$randomInt belongs to <0, 10> range")
} else {
print("$randomInt doesn't belong to <0, 10> range")
}
No doubt, the declarative approach using the range and in operator is cleaner and easier to read, compared to classic, imperative-style condition statements.
There's more...
Range expressions can enhance use of the when expression as well. In the following example, we are going to implement a simple function that will be responsible for mapping a student's exam score to a corresponding grade. Let's say we have the following enum class model for student grades:
enum class Grade { A, B, C, D }
We can define a function that will map the exam score value, in the 0 to 100 % range, to the proper grade (A, B, C, or D) using a when expression, as follows:
fun computeGrade(score: Int): Grade =
when (score) {
in 90..100 -> Grade.A
in 75 until 90 -> Grade.B
in 60 until 75 -> Grade.C
in 0 until 60 -> Grade.D
else -> throw IllegalStateException("Wrong score value!")
}
Using ranges together with the in operator makes the implementation of the computeGrade() function much cleaner and more natural than the classic equivalent implementation using traditional comparison operators, such as <, >, <=, and >=.
See also
- If you'd like to discover more about lambdas, the infix notation, and operator overloading, go ahead and dive into Chapter 2, Expressive Functions and Adjustable Interfaces