gpt4 book ai didi

Kotlin:将Sequence按N项拆分成Sequence>?

转载 作者:行者123 更新时间:2023-12-05 01:23:01 24 4
gpt4 key购买 nike

如何迭代地“取(N)”——得到一个序列 ,每个内部序列都有接下来的N个元素?

我正在用 Kotlin 编写高负载应用程序。

我有数以万计的条目要插入到数据库中。
我想以 1000 个为单位对它们进行批处理。

所以我创建了一个循环:

    val itemsSeq = itemsList.iterator().asSequence()
while (true) {
log.debug("Taking $BATCH_SIZE from $itemsSeq")
val batchSeq = itemsSeq.take(BATCH_SIZE)
val squareBatch = applySomething(batchSeq, something)
?: break
}

fun applySomething(batch: Sequence<Item>, something: Something) {
/* Fully consumes batch. Bulk-loads from DB by IDs, applies, bulk-saves. */
}

我认为 take() 会推进 itemsSeq 并且下一次调用 take() 会给我一个序列“ View ” itemsSeq 从第 10 个项目开始。

但是使用这段代码,我得到:

DEBUG Taking 10 from kotlin.sequences.ConstrainedOnceSequence@53fe15ff
Exception in thread "main" java.lang.IllegalStateException: This sequence can be consumed only once.
at kotlin.sequences.ConstrainedOnceSequence.iterator(SequencesJVM.kt:23)
at kotlin.sequences.TakeSequence$iterator$1.<init>(Sequences.kt:411)
at kotlin.sequences.TakeSequence.iterator(Sequences.kt:409)

所以看起来 take() 再次“打开”itemsSeq,而它只能消耗一次。

作为解决方法,我可以使用 chunked():

public fun <T> Sequence<T>.chunked(size: Int): Sequence<List<T>> {

但我宁愿不创建List,而是创建Sequence
我正在寻找的是 take()chunked() 之间的东西。

Kotlin SDK中有这样的东西吗?
我可以创建自己的 sequence { ... } 但为了可读性,我更喜欢内置的东西。

最佳答案

有一种方法可以通过将序列传递给迭代器来构造序列,请参阅 Sequence .

Given an iterator function constructs a Sequence that returns valuesthrough the Iterator provided by that function. The values areevaluated lazily, and the sequence is potentially infinite.

包裹在一个扩展函数中,它看起来像这样:

fun <T> Iterable<T>.toValuesThroughIteratorSequence(): Sequence<T> {
val iterator = this.iterator()
return Sequence { iterator }
}

快速测试:

data class Test(val id: Int)

val itemsList = List(45) { Test(it) }
val batchSize = 10

val repetitions = itemsList.size.div(batchSize) + 1
val itemsSeq = itemsList.toValuesThroughIteratorSequence()

(0 until repetitions).forEach { index ->
val batchSeq = itemsSeq.take(batchSize)
println("Batch no. $index: " + batchSeq.map { it.id.toString().padStart(2, ' ') }.joinToString(" "))
}

输出:

Batch no. 0:    0  1  2  3  4  5  6  7  8  9
Batch no. 1: 10 11 12 13 14 15 16 17 18 19
Batch no. 2: 20 21 22 23 24 25 26 27 28 29
Batch no. 3: 30 31 32 33 34 35 36 37 38 39
Batch no. 4: 40 41 42 43 44

关于Kotlin:将Sequence<T>按N项拆分成Sequence<Sequence<T>>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72950095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com