Take just a few from a Sequence without using it up

I’ve got a Sequence<Frame> that is constrainOnce, and I’d like to merge together the first 30 frames.

Is it possible to “nibble” 30 items off the front of the sequence without killing it for later use? Because if I .take(30), I can’t then average the next 40 frames later, because the Sequence is used up at that point.

Maybe I have to get the iterator() of it, call next() 30 times, then turn the iterator back into asSequence() at the end to continue working through the frames? But that seems hacky.

You can just us next() on iterator several times like:

val iterator = sequence.iterator()
val firstFrames = (0..29).map{
  iterator.next()
}

It won’t be terminal for sequence and it will in general affect its state, so you do not need to return anything.

To be on the safe side, you can return not the initial sequence, but the one from iterator: iterator.asSequence().

Yup! works great. Just seems odd to “bounce” through converting to an iterator and back.

It happens because Sequence is designed to consume an iterator in a safe way and “take just a few elements” is not exactly safe. You can add your own extension like:

fun <T, R> Sequence.consume(n: Int, consumer: (List<T>) -> Unit): Sequence<T>{
  consumer((0 until n).map{iterator().next()})
}