Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“消费”;页码为“;(不完全是)Scala中具有未知页面计数和未知页面大小的API_Scala_Pagination_Discord - Fatal编程技术网

“消费”;页码为“;(不完全是)Scala中具有未知页面计数和未知页面大小的API

“消费”;页码为“;(不完全是)Scala中具有未知页面计数和未知页面大小的API,scala,pagination,discord,Scala,Pagination,Discord,假设您使用的API最多提供100个元素,并允许您获取更多元素,而不是通过指定页码,而是通过告诉它您收到的最后一个元素。然后,您可能希望对这种准分页进行抽象。 在Scala你会怎么做 我提出了一段可能有错误(=未经过彻底测试)且非常有状态的代码: 抽象类迭代器ATKEEPSONGIVING[T]扩展迭代器[T]{ 私有变量currentIter:迭代器[T]=_ 私有变量currentElement:T=_ def nextIterator(lastElement:选项[T]):迭代器[T] fe

假设您使用的API最多提供100个元素,并允许您获取更多元素,而不是通过指定页码,而是通过告诉它您收到的最后一个元素。然后,您可能希望对这种准分页进行抽象。 在Scala你会怎么做

我提出了一段可能有错误(=未经过彻底测试)且非常有状态的代码:

抽象类迭代器ATKEEPSONGIVING[T]扩展迭代器[T]{
私有变量currentIter:迭代器[T]=_
私有变量currentElement:T=_
def nextIterator(lastElement:选项[T]):迭代器[T]
fetchNewBatch(无)
def fetchNewBatch(lastElement:Option[T])={
currentIter=nextIterator(最后一个元素)
}
def hasNext:Boolean=currentIter.hasNext | |{
fetchNewBatch(Some(currentElement))
哈斯奈特
}
def next():T={
currentIter.nextOption()匹配{
案例部分(值)=>
currentElement=值
价值
案例无=>
fetchNewBatch(Some(currentElement))
下一个()
}
}
}
我不喜欢它

使用:

val numberIterator=new迭代器atkeepsonging[Int]{
def nextIterator(lastElement:Option[Int]):迭代器[Int]={
val i=lastElement.getOrElse(-1)
((i+1)到(i+4))。迭代器
}
}
一定有更好的办法。当然,我不是第一个被这种分页方式困扰的人。这个词的正确名称是什么?我该如何抽象它呢

所讨论的API是Discord的消息列表API:

考虑的备选方案 我发现了这个问题:

但是,在我的例子中,我没有总页数。 这个答案还假设页面大小是恒定的,虽然在我的例子中给出了这一点,但我更喜欢只知道“我得到的最后一个元素是X。我如何得到一些更多元素?”而不是“我上一次得到X,我如何得到下一个Y元素?”的解决方案。此外,这是无关的,因为我不能直接指定页码


Akka溪流中也有同样问题的
flatMapConcat
(和
mapConcat
)。。。它看起来更好/更聪明,但在迭代时将整个页面的元素保留在内存中,而不是一次只保留一个(这可能很好,因为分页器已经保存了对它们的引用)


嗯,你可以这样做。。。它看起来更好/更聪明,但在迭代时将整个页面的元素保留在内存中,而不是一次只保留一个(这可能很好,因为分页器已经保存了对它们的引用)


非常有趣<代码>迭代!这就是它的名字。我记得在标准图书馆里有类似的东西,但我很快就停止了寻找。很高兴看到有一个版本提供了以前的值。这非常有帮助!“懒散列表”的原因是什么?你就不能这样做:
val iter:Iterator[Seq[Msg]]=Iterator.iterate(nextBatchOfMessages(None))(lastList=>nextBatchOfMessages(lastList.lastpoption));val iter2:Iterator[Msg]=iter.flatMap(u.Iterator)
?我不知道你的
nextBatch
返回什么。我不想把它限制在
IterableOnce
之外。还有
.flatMap(uu.iterator)
=
.flatten
。您确实需要
takeWhile
,因为如果没有它,您只需在完成后重新开始。这是一个很好的答案,它正好利用了为此而创建的功能。从文档:
def iterate[T](开始:T)(f:(T)=>T):迭代器[T]创建一个无限迭代器,该迭代器将给定的函数重复应用于先前的结果非常有趣<代码>迭代
!这就是它的名字。我记得在标准图书馆里有类似的东西,但我很快就停止了寻找。很高兴看到有一个版本提供了以前的值。这非常有帮助!“懒散列表”的原因是什么?你就不能这样做:
val iter:Iterator[Seq[Msg]]=Iterator.iterate(nextBatchOfMessages(None))(lastList=>nextBatchOfMessages(lastList.lastpoption));val iter2:Iterator[Msg]=iter.flatMap(u.Iterator)
?我不知道你的
nextBatch
返回什么。我不想把它限制在
IterableOnce
之外。还有
.flatMap(uu.iterator)
=
.flatten
。您确实需要
takeWhile
,因为如果没有它,您只需在完成后重新开始。这是一个很好的答案,它正好利用了为此而创建的功能。从文档:
def iterate[T](开始:T)(f:(T)=>T):迭代器[T]创建一个无限迭代器,该迭代器将给定的函数重复应用于先前的结果
fwiw I对上述迭代器做了一个稍微改进和稍微测试的版本:fwiw I对上述迭代器做了稍微改进和稍微测试的版本:
 Iterator
   .iterate(fetchNewBatch(None).to(LazyList)) { 
      fetchNewBatch(_.lastOption).to(LazyList)
   }.takeWhile(_.nonEmpty)
    .flatten