我正在用 Ruby 实现一个循环,但它看起来很难看,我想知道是否有更简洁、更像 Ruby 的编写方式:
def get_all_items
items = []; page = 1; page_items = nil
while page_items != [] # Loop runs until no more items are received
items += (page_items = get_page_items(page))
page += 1
end
items
end
请注意,get_page_items
方法运行 HTTP 请求以获取页面的项目,并且无法知道页面数、项目总数或在实际执行请求之前为任何页面添加项目,直到其中一个返回空项目集。
想象一下翻阅目录并记下所有产品,而事先不知道它有多少页或有多少产品。
最佳答案
我认为这个特殊问题很复杂,因为 A) 没有用于获取项目总数的 API 和 B) 来自 get_page_items
的响应总是真实的。此外,迭代调用肯定会以任意限制向您的数据库发出单独请求的方法,只是为了将它们连接在一起,这对您来说没有意义。冒着重复自己的风险,您应该实现此方法以提示数据库查询(即 model.all
)。
通常,当您定义一个空集合、迭代和转换一个集合,然后返回一个结果时,您应该使用 reduce
(又名 inject
):
array.reduce(0) { |result, item| result + item } # a quick sum
如果不使用 Enumerable,您需要在同一进程中执行某种形式的流式处理,这使得这很困难。我发现这是一个很好的折衷方案,可读性更高,即使过多地抚摸这个 items
变量有点令人反感:
items = []
begin
items << page_items = get_page_items(page ||= 1)
page += 1
end until page_items.empty?
items.flatten
关于ruby - 如何以更简洁的方式重写这个 Ruby 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7045298/