Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.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中执行结果分页的更好方法_Scala_Pagination_Paging - Fatal编程技术网

在Scala中执行结果分页的更好方法

在Scala中执行结果分页的更好方法,scala,pagination,paging,Scala,Pagination,Paging,我经常进行结果分页(给定一个页码和一个页面大小来计算起始、结束和总页面),我从Java移植了这个小函数来帮助: def page(page: Int, pageSize: Int, totalItems: Int) = { val from = ((page - 1) * pageSize) + 1 var to = from + pageSize - 1 if (to > totalItems) to = totalItems var totalPages

我经常进行结果分页(给定一个页码和一个页面大小来计算起始、结束和总页面),我从Java移植了这个小函数来帮助:

def page(page: Int, pageSize: Int, totalItems: Int) = {
    val from = ((page - 1) * pageSize) + 1
    var to = from + pageSize - 1
    if (to > totalItems) to = totalItems
    var totalPages: Int = totalItems / pageSize
    if (totalItems % pageSize > 0) totalPages += 1
    (from, to, totalPages)
}
在接受方:

val (from, to, totalPages) = page(page, pageSize, totalItems)
虽然它可以工作,但我确信在Scala中有更多可读性和功能性的方法来做同样的事情。什么是更像scala的方法

特别是,我试图找到一种更好的表达方式:

var to = from + pageSize - 1
if (to > totalItems) to = totalItems
在Java中,我可以执行以下操作:

from + pageSize - 1 + (to > totalItems) ? 1 : 0;

最简单的改进是只使用函数而不是变量(并避免用参数名隐藏方法名,因此无论是否调用递归函数都更清晰):


关键的变化只是使用
min
函数而不是单独的变量,并让
if
语句返回0或1,而不是让它更新变量。

问题的一半是识别模式:

def pageCalc(page: Int, pageSize: Int, totalItems: Int) = {
    val pages = 1 to totalItems by pageSize
    val from = pages(page - 1)
    val to = from + pageSize - 1 min totalItems
    val totalPages = pages.size
    (from, to, totalPages)
}

不过,真的,也许你可以直接使用
范围

谢谢雷克斯。我同意函数名的更改。我只是很快地把一些东西拼凑起来,以确保它被编译。我认为“min”是一个明显的改进,“if”解决了var的使用问题。如果有更简洁的东西,那会更好在Java中。@Ike-没有内置的三元运算符,但是您可以很容易地定义自己的运算符。比如说,我看到了。非常有趣的帖子。对于“相对较少”的收益来说,这似乎是一个过于复杂的解决方案(甚至不考虑评论中提出的性能影响)。我认为你提出的上述修改达到了正确的平衡。再次感谢。顺便说一句,在我将代码简化为与开始时几乎相同的内容之前,由于一些简单的错误,我对代码进行了大量的编辑,这让我印象深刻。谢谢Daniel。我不知道射程中的“by”。这里有一个有趣的应用程序。我们通过创建一个巧妙的集合来避免一些算术运算。我想这是品味的问题。不确定大量totalItems的性能影响和可伸缩性考虑因素,但我认为这些因素与此的大多数实际用途无关。@实际上,所有算术运算都隐藏在
范围内。当我做
pages(第1页)
时,它所做的计算与您和Rex所做的几乎相同——因此,具有几乎相同的性能。事实上,
Range
可能是Scala中最优化的集合。不管怎样,主要的优点是你不需要“解码”算法来理解代码。第二个主要优点是减少了出现bug的机会。
def pageCalc(page: Int, pageSize: Int, totalItems: Int) = {
    val pages = 1 to totalItems by pageSize
    val from = pages(page - 1)
    val to = from + pageSize - 1 min totalItems
    val totalPages = pages.size
    (from, to, totalPages)
}