generateSequence

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.

Since Kotlin

1.0

See also

Samples

import kotlin.test.*

fun main() { 
   //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
}

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.

Since Kotlin

1.0

See also

Samples

import kotlin.test.*

fun main() { 
   //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
}

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.

Since Kotlin

1.0

See also

Samples

import kotlin.test.*

fun main() { 
   //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
}