I want to achieve something like this: ```val seq:...
# stdlib
j
I want to achieve something like this:
Copy code
val seq: Sequence<Int> = ...
seq.takeWhile { it < 100 }.forEach { println("small: $it") }
seq.drop(???).takeWhile { it < 200 }.forEach { println("medium: $it") }
seq.drop(???).forEach { it < 300 }.forEach { println("large: $it" }
but I’m wondering if there’s something more idiomatic/elegant than the `drop()`s. I tried having the Sequence maintain the same iterator, but that skips the items for which the
takeWhile {}
returns false (because
next()
is called regardless). Any ideas?
e
I suppose you want something like
Copy code
val (small, notSmall) = seq.partition { it < 100 }
val (medium, large) = notSmall.partition { it < 200 }
but more lazily?
o
Copy code
val seq = sequenceOf(1, 110, 210, 2, 310, 3)

seq.groupBy {
    if (it < 100) "small" else (if (it < 200) "medium" else "large")
}.forEach { category, values ->
    for (value in values)
        println("$category: $value")
}
Even better:
Copy code
val seq = sequenceOf(1, 110, 210, 2, 310, 3)

seq.groupBy {
    when (it) {
        in 0 until 100 -> "small"
        in 100 until 200 -> "medium"
        else -> "large"
    }
}.forEach { category, values ->
    for (value in values)
        println("$category: $value")
}
e
the original
takeWhile
is lazier than `groupBy`; it doesn't require consuming the entire sequence to produce the first value
now, you could do something like
Copy code
seq.groupingBy { ... }
to maintain some laziness, but it still has different behavior than the original due to its behavior w.r.t. ordering
this is fully lazy but delicate
🙌 1
👍 2
if somebody could come up with a better API, perhaps something could get into stdlib
o
Requires a pre-ordered sequence to start with, but if complete laziness is a must, seems absolutely viable. I wonder if the API could really be significantly simplified, given the inherent complexity. 👏