generateSequence

Common
JVM
JS
Native
1.0
fun <T : Any> generateSequence(
    nextFunction: () -> T?
): Sequence<T>

(source)

Returns a sequence which invokes the function to calculate the next value on each iteration until the function returns null.

The returned sequence is constrained to be iterated only once.

import kotlin.test.*

fun main(args: Array<String>) {
//sampleStart
var count = 3

val sequence = generateSequence {
    (count--).takeIf { it > 0 } // will return null, when value becomes non-positive,
                                // and that will terminate the sequence
}

println(sequence.toList()) // [3, 2, 1]

// sequence.forEach {  }  // <- iterating that sequence second time will fail
//sampleEnd
}

See Also

constrainOnce

kotlin.sequences.sequence

Common
JVM
JS
Native
1.0
fun <T : Any> generateSequence(
    seed: T?,
    nextFunction: (T) -> T?
): Sequence<T>

(source)

Returns a sequence defined by the starting value seed and the function nextFunction, which is invoked to calculate the next value based on the previous one on each iteration.

The sequence produces values until it encounters first null value. If seed is null, an empty sequence is produced.

The sequence can be iterated multiple times, each time starting with seed.

import kotlin.test.*

fun main(args: Array<String>) {
//sampleStart
fun fibonacci(): Sequence<Int> {
    // fibonacci terms
    // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, ...
    return generateSequence(Pair(0, 1), { Pair(it.second, it.first + it.second) }).map { it.first }
}

println(fibonacci().take(10).toList()) // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
//sampleEnd
}

See Also

kotlin.sequences.sequence

Common
JVM
JS
Native
1.0
fun <T : Any> generateSequence(
    seedFunction: () -> T?,
    nextFunction: (T) -> T?
): Sequence<T>

(source)

Returns a sequence defined by the function seedFunction, which is invoked to produce the starting value, and the nextFunction, which is invoked to calculate the next value based on the previous one on each iteration.

The sequence produces values until it encounters first null value. If seedFunction returns null, an empty sequence is produced.

The sequence can be iterated multiple times.

import kotlin.test.*

fun main(args: Array<String>) {
//sampleStart
class LinkedValue<T>(val value: T, val next: LinkedValue<T>? = null)

fun <T> LinkedValue<T>?.asSequence(): Sequence<LinkedValue<T>> = generateSequence(
    seedFunction = { this },
    nextFunction = { it.next }
)

fun <T> LinkedValue<T>?.valueSequence(): Sequence<T> = asSequence().map { it.value }

val singleItem = LinkedValue(42)
val twoItems = LinkedValue(24, singleItem)

println(twoItems.valueSequence().toList()) // [24, 42]
println(singleItem.valueSequence().toList()) // [42]
println(singleItem.next.valueSequence().toList()) // []
//sampleEnd
}

See Also

kotlin.sequences.sequence