Jeroen
Jeroen

Reputation: 16815

Take part of a sequence in Kotlin

I am trying to partially consume a sequence in Kotlin, in order to split it up.

fun main() {
    val seq = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).asSequence()
    println(seq.take(4).toList().toString());
    println(seq.toList().toString())
}

This outputs:

[0, 1, 2, 3]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 90]

But what I am after, is this:

[0, 1, 2, 3]
[4, 5, 6, 7, 8, 90]

Making the lists is for demonstration purposes only. As such, creating a list of the entire sequence and splitting the list is not the answer I am after.

Upvotes: 2

Views: 860

Answers (3)

Jeroen
Jeroen

Reputation: 16815

I figured out we can use iterators for this:

fun main() {
    val seq = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).asSequence().iterator()
    println(seq.asSequence().take(4).toList().toString());
    println(seq.asSequence().toList().toString())
}

This way the sequences advance the inner iterator. If the sequence was originally obtained from an Iterable, as is the case above, we can simplify even further:

fun main() {
    val seq = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).iterator()
    println(seq.asSequence().take(4).toList().toString());
    println(seq.asSequence().toList().toString())
}

Upvotes: 1

Tenfour04
Tenfour04

Reputation: 93581

You can create two subsequences from the original:

    val seq = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).asSequence()
    val firstCount = 4
    val first = seq.take(firstCount)
    val second = seq.drop(firstCount)

    println(first.toList())
    println(second.toList())

Upvotes: 4

IR42
IR42

Reputation: 9672

There is asSequence() function for iterator, but it returns sequence that can be iterated only once. The point is to use the same iterator for each iteration.

// I don't know how to name the function...
public fun <T> Iterable<T>.asIteratorSequence(): Sequence<T> {
    val iterator = this.iterator()
    return Sequence { iterator }
}

fun main() {
    val seq = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).asIteratorSequence()

    println(seq.take(4).toList().toString()) // [0, 1, 2, 3]
    println(seq.toList().toString()) // [4, 5, 6, 7, 8, 9]
    println(seq.toList().toString()) // []
}

Upvotes: 6

Related Questions