Kotlin Ranges

Ranges express a sequence of values between two endpoints and power loops, conditions, and collection slicing.

Creating a Range with ..

The .. operator creates an inclusive range, meaning both the start and end values are included in the sequence. Ranges can hold numbers or characters, and they implement Iterable, so they can be used directly in for loops or converted to a list.

Basic inclusive range

fun main() {
    val range = 1..5

    for (i in range) {
        print("$i ")
    }
    println()
    println("Contains 3? ${3 in range}")
}

Excluding the End with until

When you want to exclude the upper bound - a common need when working with array indices - use until instead of ... The expression 0 until size produces exactly the valid indices of an array of that size.

Half-open range with until

fun main() {
    val size = 5
    for (i in 0 until size) {
        print("$i ")
    }
    // Output: 0 1 2 3 4 (5 is excluded)
}

Counting Down with downTo

Ranges built with .. always count upward. To iterate in descending order, use downTo, which produces values from the higher number to the lower one.

Counting down

fun main() {
    for (i in 10 downTo 1) {
        print("$i ")
    }
    println("Liftoff!")
}

Skipping Values with step

The step keyword changes the increment between consecutive values. It can be combined with both ascending ranges and downTo to skip multiple values at a time. The step value must always be positive; direction is controlled by .. versus downTo.

Using step

fun main() {
    for (i in 0..20 step 5) {
        print("$i ")
    }
    println()

    for (i in 20 downTo 0 step 4) {
        print("$i ")
    }
}

Ranges Beyond Numbers

Character ranges work exactly like numeric ranges, which makes them convenient for tasks like validating letter grades or looping through the alphabet.

  • 'a'..'z' - all lowercase letters
  • 1..100 step 10 - every tenth number up to 100
  • 10 downTo 0 - a countdown sequence
  • range.first, range.last, range.step - inspect a range's properties directly
ExpressionProducesIncludes End?
1..51, 2, 3, 4, 5Yes
1 until 51, 2, 3, 4No
5 downTo 15, 4, 3, 2, 1Yes
1..10 step 31, 4, 7, 10Yes
Note: Ranges are objects, not just loop syntax. You can store one in a variable, pass it to a function, and check membership with the in operator, such as if (score in 90..100).
Note: Forgetting downTo when counting backward is a common bug: writing for (i in 10..1) produces an empty range because .. only counts upward, so the loop body never executes.

Exercise: Kotlin Ranges

Which values are included in the range 1..5?