Ranges and Progressions

    Integral type ranges (IntRange, , CharRange) have an extra feature: they can be iterated over. These ranges are also of the corresponding integral types. Such ranges are generally used for iteration in the for loops.

    1. fun main() {
    2. //sampleStart
    3. for (i in 1..4) print(i)
    4. //sampleEnd
    5. }

    To iterate numbers in reverse order, use the downTo function instead of ...

    1. fun main() {
    2. //sampleStart
    3. for (i in 4 downTo 1) print(i)
    4. //sampleEnd
    5. }

    It is also possible to iterate over numbers with an arbitrary step (not necessarily 1). This is done via the function.

    1. fun main() {
    2. //sampleStart
    3. for (i in 1..8 step 2) print(i)
    4. println()
    5. for (i in 8 downTo 1 step 2) print(i)
    6. //sampleEnd
    7. }

    To iterate a number range which does not include its end element, use the until function:

    To create a range for your class, call the rangeTo() function on the range start value and provide the end value as an argument. is often called in its operator form ...

    1. override fun compareTo(other: Version): Int {
    2. if (this.major != other.major) {
    3. return this.major - other.major
    4. }
    5. return this.minor - other.minor
    6. }
    7. }
    8. fun main() {
    9. //sampleStart
    10. val versionRange = Version(1, 11)..Version(1, 30)
    11. println(Version(0, 9) in versionRange)
    12. println(Version(1, 20) in versionRange)
    13. //sampleEnd
    14. }

    Progression

    As shown in the examples above, the ranges of integral types, such as Int, Long, and Char, can be treated as arithmetic progressions of them. In Kotlin, these progressions are defined by special types: , LongProgression, and .

    Progressions have three essential properties: the first element, the last element, and a non-zero step. The first element is first, subsequent elements are the previous element plus a step. Iteration over a progression with a positive step is equivalent to an indexed for loop in Java/JavaScript.

    1. for (int i = first; i <= last; i += step) {
    2. // ...
    3. }

    When you create a progression implicitly by iterating a range, this progression’s first and last elements are the range’s endpoints, and the is 1.

    1. fun main() {
    2. for (i in 1..10) print(i)
    3. //sampleEnd
    4. }

    The last element of the progression is calculated this way:

    • For a positive step: the maximum value not greater than the end value such that (last - first) % step == 0.
    • For a negative step: the minimum value not less than the end value such that (last - first) % step == 0.

    Thus, the last element is not always the same as the specified end value.

    1. fun main() {
    2. //sampleStart
    3. for (i in 1..9 step 3) print(i) // the last element is 7
    4. //sampleEnd
    5. }

    To create a progression for iterating in reverse order, use downTo instead of .. when defining the range for it.

    1. fun main() {
    2. //sampleStart
    3. for (i in 4 downTo 1) print(i)
    4. //sampleEnd
    5. }

    Progressions implement Iterable<N>, where N is Int, Long, or Char respectively, so you can use them in various collection functions like map, filter, and other.

    1. fun main() {
    2. //sampleStart
    3. println((1..10).filter { it % 2 == 0 })
    4. //sampleEnd