gpt4 book ai didi

java - 如何使用关心下一个元素的谓词来限制 Kotlin 序列?

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

我需要处理一个返回分 block 数据的 API。

val response = server.getChunk(request, chunkNumber)

data class PageInfo(
val pageNumber: Int,
val maxPages: Int
)
data class Response(
val elements: List<Payload>,
val pageInfo: PageInfo
)

我假设这个 API 是幂等的。

我可以做类似的事情(拿 1):

var i = 0
var maxPages: Int
val payloadTotal = mutableListOf<Payload>()
do {
val response = server.getChunk(request, i++)
maxPages = response.pageInfo.maxPages
payloadTotal.addAll(response.payload)
} while (i < maxPages)

它有效,但它很丑。

采取 2:

val partners = IntStream
.iterate(0) { it + 1 }
.asSequence()
.map { server.getChunk(request, it) }
.takeWhile { it.pageInfo.pageNumber < it.pageInfo.maxPages }
.map { it.payload }
.flatten()
.toList()

它看起来好多了,但并没有完全按预期工作:因为我们在已经请求服务器之后检查 takeWhile 谓词,所以我们总是会做一个额外的请求。由于我们在执行第一个请求之前不知道 maxPages 值,因此我们不能使用类似 take(n: Int) 的东西。

所以我最终使用了该代码(取 3):

var maxPages = Int.MAX_VALUE
val partners = IntStream
.iterate(0) { it + 1 }
.asSequence()
.takeWhile { it < maxPages }
.map {
server.getChunk(request, it)
.also { response -> maxPages = response.pageInfo.maxPages }
}
.map { it.payload }
.flatten()
.toList()

它有效。但话又说回来,我们使用了这个我不喜欢的额外状态。

此外,由于“有效最终”限制,这在 Java 中根本不起作用(我希望它能作为奖励)。

那么如何使用函数式方法实现所需的行为呢?有没有办法在不跟踪管道外的任何添加状态的情况下做到这一点?

*如果存在这种方式,它是否也可以转换为 Java?

最佳答案

我们可以为此创建自己的序列运算符。它需要编写一些代码,但我们可以很好地使用它:

generateSequence(0) { it + 1 }
.map { server.getChunk(request, it) }
.takeNextWhile { it.pageInfo.pageNumber + 1 < it.pageInfo.maxPages }
.flatMap { it.elements }
.toList()

fun <T> Sequence<T>.takeNextWhile(predicate: (T) -> Boolean): Sequence<T> = Sequence {
val iter = iterator()
var hasNext = iter.hasNext()
object : Iterator<T> {
override fun hasNext() = hasNext
override fun next() = iter.next().also { hasNext = iter.hasNext() && predicate(it) }
}
}

或者,如果对我们来说更有意义,我们可以将其命名为 takeWhilePrevious()

如果我们不想创建新的运算符,那么我认为最好不要使用函数转换,因为在这种情况下它们会降低代码的可读性。假设 maxPages 不变,我们可以先获取它,然后执行一个非常简单的循环:

val first = server.getChunk(request, 0)
val payloads = first.elements.toMutableList()
(1 until first.pageInfo.maxPages).forEach {
payloads += server.getChunk(request, it).elements
}

关于java - 如何使用关心下一个元素的谓词来限制 Kotlin 序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70832326/

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