Kotlin Ranges

Ranges represent a sequence of values defined by a start, an end, and an optional step. They simplify iteration, containment checks, and boundary validations.

1. Creating an Inclusive Range

Use .. to define an inclusive IntRange:

val range: IntRange = 1..5
println(range)       // 1..5
println(range.first) // 1
println(range.last)  // 5
println(range.step)  // 1 (default)

2. Containment Checks

Test membership with in and !in:

println(3 in 1..5)   // true
println(0 in 1..5)   // false
println(6 !in 1..5)  // true

3. Exclusive End with until

until creates a half-open range excluding the end:

for (i in 0 until 5) {
  print("$i ")
}

Output: 0 1 2 3 4

4. Descending Ranges with downTo

Iterate downward:

for (i in 5 downTo 1) {
  print("$i ")
}

Output: 5 4 3 2 1

5. Custom Step with step

Specify the interval between elements:

for (i in 1..10 step 2) {
  print("$i ")
}
println()
for (j in 10 downTo 1 step 3) {
  print("$j ")
}

Output: 1 3 5 7 9
10 7 4 1

6. Character Ranges

Ranges can also be defined for Char:

for (c in 'a'..'e') {
  print(c)
}
println()
println('z' in 'a'..'m')

Output: abcde
false

7. Progressions

A step or downTo range produces an IntProgression:

val prog: IntProgression = 1..10 step 3
println(prog)       // 1..10 step 3
println(prog.step)  // 3

8. Iterating over Progressions

Use a for loop directly:

for (x in prog) {
  print("$x ")
}

Output: 1 4 7 10

9. Converting to Collections

Call toList() to obtain a List<Int>:

val list: List<Int> = (1..5).toList()
println(list)  // [1, 2, 3, 4, 5]

10. Summary & Best Practices

- Use .. for inclusive ranges.
- Prefer until when excluding the end.
- Combine downTo & step for custom iteration.
- Leverage character ranges for alphabetic loops.
- Convert to collections for random access.
- Document non-obvious steps clearly.
- Avoid very large ranges without a step to prevent performance issues.

Previous: Kotlin Loops | Next: Kotlin Lambdas

<
>