Kotlin Ranges
Ranges are a powerful feature in Kotlin that allow you to express sequences of values concisely. They are particularly useful for iteration and for checking if values fall within specific boundaries. In this tutorial, we'll explore how to use ranges effectively in your Kotlin programs.
Introduction to Ranges
A range in Kotlin represents a sequence of values with a start value and an end value. Ranges are inclusive by default, meaning both the start and end values are included in the range. Kotlin provides a simple syntax for creating ranges using the ..
operator.
Creating Basic Ranges
Integer Ranges
Let's start with the most common type of range - integer ranges:
// Creating an integer range from 1 to 5 (inclusive)
val oneToFive = 1..5
// This is equivalent to
val oneToFiveAlternative = IntRange(1, 5)
println("Range: $oneToFive")
Output:
Range: 1..5
Character Ranges
Kotlin also supports character ranges:
// Creating a character range from 'a' to 'e'
val aToE = 'a'..'e'
println("Character range: $aToE")
Output:
Character range: a..e
Iterating Through Ranges
One of the most common uses of ranges is for iteration in for loops:
// Iterating through an integer range
for (i in 1..5) {
print("$i ")
}
Output:
1 2 3 4 5
Iterating in Reverse
To iterate backwards, you can use the downTo
function:
// Counting down from 5 to 1
for (i in 5 downTo 1) {
print("$i ")
}
Output:
5 4 3 2 1
Using Step
You can specify a step (increment) value using the step
function:
// Counting from 1 to 10 in steps of 2
for (i in 1..10 step 2) {
print("$i ")
}
Output:
1 3 5 7 9
You can also combine downTo
and step
:
// Counting down from 10 to 1 in steps of 3
for (i in 10 downTo 1 step 3) {
print("$i ")
}
Output:
10 7 4 1
Exclusive Ranges (Until)
If you want to exclude the upper bound, use the until
function:
// Range from 1 to 4 (5 is excluded)
for (i in 1 until 5) {
print("$i ")
}
Output:
1 2 3 4
Checking Values with Ranges
Ranges are useful for checking if a value is within a specific interval:
val age = 25
if (age in 18..65) {
println("$age is within the working age range")
} else {
println("$age is outside the working age range")
}
val letter = 'c'
if (letter in 'a'..'z') {
println("$letter is a lowercase letter")
}
// You can also check if a value is NOT in a range
val temperature = -5
if (temperature !in 0..40) {
println("$temperature is outside the allowed temperature range")
}
Output:
25 is within the working age range
c is a lowercase letter
-5 is outside the allowed temperature range
Ranges with Non-Primitive Types
Kotlin ranges work with any type that implements the Comparable
interface and has the next()
and hasNext()
functions. However, the standard library mainly supports ranges of primitive types: integers, characters, and string comparisons.
Real-World Examples
Example 1: Input Validation
fun validateUserInput(input: Int): Boolean {
return input in 1..100
}
// Testing the validation function
val userInput = 42
val isValid = validateUserInput(userInput)
println("Is input $userInput valid? $isValid")
val invalidInput = 150
println("Is input $invalidInput valid? ${validateUserInput(invalidInput)}")
Output:
Is input 42 valid? true
Is input 150 valid? false
Example 2: Grade Classification
fun getGradeDescription(score: Int): String {
return when(score) {
in 90..100 -> "Excellent"
in 80 until 90 -> "Very Good"
in 70 until 80 -> "Good"
in 60 until 70 -> "Satisfactory"
in 0 until 60 -> "Fail"
else -> "Invalid Score"
}
}
// Testing the grade classification
println("Score 95: ${getGradeDescription(95)}")
println("Score 82: ${getGradeDescription(82)}")
println("Score 45: ${getGradeDescription(45)}")
println("Score -5: ${getGradeDescription(-5)}")
Output:
Score 95: Excellent
Score 82: Very Good
Score 45: Fail
Score -5: Invalid Score
Example 3: Season Determination
fun determineSeason(month: Int): String {
return when(month) {
in 3..5 -> "Spring"
in 6..8 -> "Summer"
in 9..11 -> "Fall"
12, in 1..2 -> "Winter"
else -> "Invalid Month"
}
}
// Testing season determination
for (month in 1..12) {
println("Month $month is in ${determineSeason(month)}")
}
Output:
Month 1 is in Winter
Month 2 is in Winter
Month 3 is in Spring
Month 4 is in Spring
Month 5 is in Spring
Month 6 is in Summer
Month 7 is in Summer
Month 8 is in Summer
Month 9 is in Fall
Month 10 is in Fall
Month 11 is in Fall
Month 12 is in Winter
Ranges and Collections
Ranges can be converted to collections when needed:
// Converting a range to a list
val rangeList = (1..5).toList()
println("Range as list: $rangeList")
// Creating an array from a range
val rangeArray = (1..5).toList().toTypedArray()
println("Range as array: ${rangeArray.joinToString()}")
Output:
Range as list: [1, 2, 3, 4, 5]
Range as array: 1, 2, 3, 4, 5
Summary
Ranges in Kotlin provide a concise way to:
- Create sequences of values (integers, characters, etc.)
- Iterate through sequences in forward or reverse order
- Check if values are within specific boundaries
- Use steps to skip values in a sequence
They are particularly useful for:
- Loop control
- Input validation
- Value categorization
- When expressions
Ranges may seem like a simple feature, but they greatly improve code readability and help reduce errors in boundary conditions.
Exercises
-
Write a function that takes an integer and returns whether it's a leap year (divisible by 4, but not by 100 unless also divisible by 400).
-
Create a function that prints a simple ASCII chart using character ranges.
-
Implement a "FizzBuzz" program using ranges: For numbers 1 to 100, print "Fizz" for numbers divisible by 3, "Buzz" for numbers divisible by 5, and "FizzBuzz" for numbers divisible by both.
-
Write a function that determines if a given password is strong enough by checking if it contains at least one character from each of these ranges: lowercase letters, uppercase letters, digits, and symbols.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)