【问题标题】:Enumerate lazily until the block is false懒惰地枚举,直到块为假
【发布时间】:2019-02-25 11:06:11
【问题描述】:

我编写了一个 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

但我开始意识到这一切都是在执行一个返回 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

【问题讨论】:

    标签: ruby enumerable


    【解决方案1】:

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

    如果您将多个值传递给 yield,它们会一次全部生成,而您希望一个接一个地生成它们。既然你有障碍:

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

    这将产生 3 个收益。第一个带有参数1,第二个带有参数1, 2,第三个带有参数1, 2, 3。如果您想将它们作为单独的收益进行收益,则必须更改以下内容:

    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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 2018-04-28
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      相关资源
      最近更新 更多