gpt4 book ai didi

ruby - 惰性枚举直到 block 为假

转载 作者:数据小太阳 更新时间:2023-10-29 08:42:44 24 4
gpt4 key购买 nike

我编写了一个 Enumerable 类来无缝地延迟获取 API 请求的所有页面。

class Pager
include Enumerable

def initialize(&fetch_next_page)
@fetch_next_page = fetch_next_page
reset
end

def reset
@page_number = 0
end

private def next_page
@page_number += 1

return @fetch_next_page.call(@page_number)
end

def each(&block)
if block_given?
while resp = next_page
resp.each(&block)
end
reset
else
to_enum(:each)
end
end
end

这是一个如何使用它的例子。

pager = Pager.new do |page_number|
response = fetch_page( page: page_number, **some_options )

response.page <= response.total_pages ? response.stuff : false
end

但我开始意识到所有这一切都在执行一个 block ,该 block 返回一个 Enumerable 直到它为 false,并且它正在展平 Enumerables。

pager = Pager.new { |page_number|
page_number <= 3 ? 1.upto(page_number) : false
}

# [1, 1, 2, 1, 2, 3]
puts pager.to_a.inspect

有没有更简单的方法来做到这一点?我已经接近 Enumerator,但无法使扁平化工作。

def paginate(&fetch_next)
return Enumerator.new do |yielder|
page_number = 1
while ret = fetch_next.call(page_number)
yielder.yield(*ret)
page_number += 1
end
end
end

pager = paginate { |page_number|
page_number <= 3 ? 1.upto(page_number) : false
}

# [1, [1, 2], [1, 2, 3]]
puts pager.to_a.inspect

最佳答案

枚举器输出不正确的原因确实与 splat 运算符有关。

如果您将多个值传递给yield,它们会一次全部产生,而您希望一个一个地产生它们。既然你已经得到了 block :

{ |page_number| page_number <= 3 ? 1.upto(page_number) : false }

这将产生 3 个产量。第一个参数为 1,第二个参数为 1, 2,第三个参数为 1, 2, 3。如果您想将它们作为单独的 yield 来产生,您必须更改以下内容:

yielder.yield(*ret)

# should be changed to

ret.each { |e| yielder.yield e }
# or
ret.each { |e| yielder << e }
# depending on your preference

pager.to_a
#=> [1, 1, 2, 1, 2, 3]

关于ruby - 惰性枚举直到 block 为假,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52436934/

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