smichel17
10/15/2021, 1:09 PMSequence.takeWhile
? E.g. one of these:
fun <T>Sequence<T>.takeThenWhile(count: Int, predicate: (T) -> Boolean): Sequence<T> {
var i = 0
return this.takeWhile{ i < count || predicate(it) }.onEach { i++ }
}
fun <T>Sequence<T>.takeWhileIndexed(predicate: (Int, T) -> Boolean): Sequence<T> {
var i = 0
return takeWhile { predicate(i, it) }.onEach { i++ }
}
Both take
and takeWhile
could be implemented in terms of this function
fun <T>Sequence<T>.take(count: Int) = takeThenWhile(count) { false }
fun <T>Sequence<T>.takeWhile(predicate: (T) -> Boolean) = takeThenWhile(0, predicate)
fun <T>Sequence<T>.take(count: Int) = takeWhileIndexed { i, _ -> i < count }
fun <T>Sequence<T>.takeWhile(predicate: (T) -> Boolean) = takeWhileIndexed { _, t -> predicate(t) }
gian
10/15/2021, 1:51 PMwithIndex()
?
sequenceOf("a").withIndex().takeWhile { (index, value) -> }
smichel17
10/15/2021, 4:37 PMwithIndex
😅smichel17
10/15/2021, 5:28 PMfun <T>Sequence<T>.takeThenWhile(count: Int, predicate: (T) -> Boolean): Sequence<T> {
return withIndex().takeWhile{ (i, t) -> i < count || predicate(t) }.map { it.value }
}
ephemient
10/15/2021, 8:45 PMsmichel17
10/15/2021, 8:47 PMsmichel17
10/15/2021, 8:49 PMephemient
10/15/2021, 8:54 PMval s = .takeWhileIndexed(); s.forEach(); s.forEach()
. you could use the sequence builder,
fun <T> Sequence<T>.takeWhileIndexed(count: Int, predicate: (Int, T) -> Boolean): Sequence<T> = sequence {
if (count <= 0) return@sequence
var i = 0
for (item in this@takeWhileIndexed) {
if (!predicate(i, item)) break
yield(item)
if (++i >= count) break
}
}
in which case the variable is scoped to each iteratorephemient
10/15/2021, 8:56 PMtakeWhileThen
any different from .take.takeWhile
?ephemient
10/15/2021, 8:57 PMsmichel17
10/15/2021, 8:57 PMtakeThenTakeWhile
.smichel17
10/15/2021, 8:58 PMprivate fun <T> Sequence<T>.countUnique(minItems: Int, uniqueValues: Int): Map<T, Int> {
val counts = mutableMapOf<T, Int>()
val items = takeThenWhile(minItems) { counts.size < uniqueValues }.filterNotNull()
return items.groupingBy { it }.eachCountTo(counts)
}
smichel17
10/15/2021, 8:59 PMminItems
, but if it finds fewer than uniqueValues
, it'll keep going until it finds that many (or the sequence ends, obviously)smichel17
10/15/2021, 9:00 PMsmichel17
10/15/2021, 9:15 PMtake
might have the same problem with double iteration? https://github.com/JetBrains/kotlin/blob/b65c477e68d2e4e3b635d63b7cdc61f41829d472/libraries/stdlib/src/kotlin/collections/Sequences.kt#L397 (The actual extension function is just slightly larger than Sequence.take(n: Int) = TakeSequence(this, n)
)smichel17
10/15/2021, 9:40 PMtakeAtLeastWhile
:)ephemient
10/15/2021, 10:34 PMtake
is fine, it's doing the same thing at a lower levelephemient
10/18/2021, 9:44 PMsmichel17
10/18/2021, 10:07 PMsequence {}
does the same thing.