Spec-Zone.ru › Kotlin 1.4

Диапазоны и прогрессии

Kotlin позволяет легко создавать диапазоны значений, используя функцию rangeTo() из пакета kotlin.ranges и её операторную форму ... Обычно rangeTo() дополняется функциями in или !in.

if (i in 1..4) {  // equivalent of 1 <= i && i <= 4
    print(i)
}

Диапазоны целочисленных типов (IntRange, LongRange, CharRange) имеют дополнительную возможность: они могут быть итерированы. Эти диапазоны также являются прогрессиями соответствующих целочисленных типов. Такие диапазоны обычно используются для итерации в циклах for.

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

Для итерации чисел в обратном порядке используйте функцию downTo вместо ...

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

Также возможно итерировать числа с произвольным шагом (не обязательно 1). Это делается с помощью функции step.

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

Для итерации диапазона чисел, не включающего конечный элемент, используйте функцию until:

fun main() {
//sampleStart
    for (i in 1 until 10) {       // i in [1, 10), 10 is excluded
        print(i)
    }
//sampleEnd
}

Диапазон

Диапазон определяет замкнутый интервал в математическом смысле: он определяется своими двумя граничными значениями, которые оба включены в диапазон. Диапазоны определены для сравнимых типов: имея порядок, можно определить, находится ли произвольный экземпляр в диапазоне между двумя данными экземплярами. Основная операция над диапазонами — contains, которая обычно используется в форме операторов in и !in.

Чтобы создать диапазон для своего класса, вызовите функцию rangeTo() для начального значения диапазона и передайте конечное значение в качестве аргумента. rangeTo() часто вызывается в операторной форме ...

class Version(val major: Int, val minor: Int): Comparable<Version> {
    override fun compareTo(other: Version): Int {
        if (this.major != other.major) {
            return this.major - other.major
        }
        return this.minor - other.minor
    }
}

fun main() {
//sampleStart
    val versionRange = Version(1, 11)..Version(1, 30)
    println(Version(0, 9) in versionRange)
    println(Version(1, 20) in versionRange)
//sampleEnd
}

Прогрессия

Как показано в примерах выше, диапазоны целочисленных типов, таких как Int, Long, и Char, могут рассматриваться как арифметические прогрессии для них. В Kotlin эти прогрессии определяются специальными типами: IntProgression, LongProgression, и CharProgression.

Прогрессии имеют три существенных свойства: элемент first, элемент last, и ненулевой step. Первый элемент — first, последующие элементы — предыдущий элемент плюс step. Итерация по прогрессии с положительным шагом эквивалентна циклу с индексом for в Java/JavaScript.

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

Когда вы создаёте прогрессию неявно, итерируя диапазон, элементами first и last этой прогрессии являются граничные значения диапазона, а step равен 1.

fun main() {
//sampleStart
    for (i in 1..10) print(i)
//sampleEnd
}

Чтобы определить пользовательский шаг прогрессии, используйте функцию step для диапазона.

fun main() {
//sampleStart
    for (i in 1..8 step 2) print(i)
//sampleEnd
}

Элемент last прогрессии вычисляется следующим образом:

  • Для положительного шага: максимальное значение, не большее, чем конечное значение, такое что (last - first) % step == 0.
  • Для отрицательного шага: минимальное значение, не меньшее, чем конечное значение, такое что (last - first) % step == 0.

Таким образом, элемент last не всегда совпадает со значением указанного конечного элемента.

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

Чтобы создать прогрессию для итерации в обратном порядке, используйте downTo вместо .. при определении диапазона для неё.

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

Прогрессии реализуют Iterable<N>, где N — Int, Long, или Char соответственно, поэтому вы можете использовать их в различных функциях для коллекций, таких как map, filter, и других.

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

© 2010–2020 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/reference/ranges.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API