I want to generate a finite sequence of elements f...
# getting-started
j
I want to generate a finite sequence of elements from a collection, is there a way to signal that the sequence has ended using the sequence {} syntax? consider:
Copy code
val mySequence = sequence { 
  yield (
      when (takeSubListOf(foo, 0, n--)) { subListOfFoo ->
      hasMultipleElements(subListOfFoo) -> subListOfFoo.reduce { ... }
      hasOneElement(subListOfFoo) -> subListOfFoo.first()
      else -> //sequence ended
    }
  )
}
✅ 1
For the curious, here is a possible solution:
Copy code
val mySequence = sequence { 
    when (takeSubListOf(foo, 0, n--)) { subListOfFoo ->
    hasMultipleElements(subListOfFoo) -> yield(subListOfFoo.reduce { ... })
    hasOneElement(subListOfFoo) -> yield(subListOfFoo.first())
    else -> yieldAll(emptySequence())
  }
}
k
Or you could just not use yield.
😁 1
j
Thank you, excellent! It could be useful to showcase an example sequence chunk without yield calls at https://kotlinlang.org/docs/sequences.html for the less initiated.
s
Sequence builders are a lot like functions—they finish automatically when they reach the end of their code. So in this example, just doing nothing is fine. But in cases where you want to end the sequence early, before reaching the end of the builder code, you can also use
return@sequence
.
k
Also, it seems that you are creating either an empty sequence or a single-element sequence. You might prefer to use
sequenceOf
for that:
Copy code
val subListOfFoo = takeSubListOf(foo, 0, n--)
val mySequence = when {
    hasMultipleElements(subListOfFoo) -> sequenceOf(subListOfFoo.reduce { ... })
    hasOneElement(subListOfFoo) -> sequenceOf(subListOfFoo.first())
    else -> emptySequence()
}
Also, in your case,
subListOfFoo.reduce { ... }
will return
subListOfFoo.first()
when it only has one element, so you can get rid of that
when
branch and rely on
reduce
instead.
j
My thanks to everyone for all the great replies and insights!