Reputation: 16815
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
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
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
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