【问题标题】:Better way to do result paging in Scala在 Scala 中进行结果分页的更好方法
【发布时间】:2010-12-17 22:06:21
【问题描述】:

我经常进行结果分页(给定页码和页面大小,计算开始、结束和总页数),我从 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;

【问题讨论】:

    标签: scala pagination paging


    【解决方案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)
    }
    

    不过,真的,也许您可​​以直接使用Range 代替?

    【讨论】:

    • 附带说明,令人印象深刻的是,由于一些简单的错误导致我在将代码简化为几乎与我开始时相同的东西之前使代码变得更加复杂,因此我进行了多少次编辑。跨度>
    • 谢谢丹尼尔。我不知道 Range 中的“by”。有趣的应用在这里。我们通过创建一个聪明的集合来避免一些算术运算。我想这是一个品味问题。不确定大量 totalItems 的性能影响和可扩展性考虑因素,但我认为无论如何这些与大多数实际用途无关。
    • @Ike 实际上,所有算术运算都被Range 隐藏了。当我执行pages(page - 1) 时,它所做的计算与您和 Rex 所做的几乎相同——因此,性能几乎相同。事实上,Range 可能是 Scala 中最优化的集合。无论如何,主要优点是您不需要“解码”算术来理解代码。第二个主要优势是减少错误的机会。
    【解决方案2】:

    最简单的改进就是使用函数而不是 vars(并避免用参数名称遮蔽方法名称,因此更清楚您是否调用递归函数):

    def pageCalc(page: Int, pageSize: Int, totalItems: Int) = {
      val from = ((page - 1) * pageSize) + 1
      val to = totalItems min (from + pageSize - 1)
      val totalPages = (totalItems / pageSize) + (if (totalItems % pageSize > 0) 1 else 0)
      (from, to, totalPages)
    }
    

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

    【讨论】:

    • 谢谢雷克斯。我同意函数名称更改。我只是快速地将一些东西放在一起以确保它编译。我认为'min'是一个明显的改进,'if'解决了var的使用。如果有更简洁的东西会更好吗? : 在 Java 中。
    • @Ike - 没有内置三元运算符,但您可以轻松定义自己的运算符。例如,参见stackoverflow.com/questions/2705920
    • 我明白了。非常有趣的帖子。对于“相对较小”的增益(甚至不考虑 cmets 中提出的性能影响),它似乎确实是一个过于复杂的解决方案。我认为您提出的上述更改取得了适当的平衡。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 2012-08-29
    • 2010-09-11
    • 2017-12-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多