背景:我需要确定远程位置的记录数。记录按顺序编号(从0
开始,无间隙),并且只能根据其编号逐个获取。
通过网络获取记录的方法在成功时返回 truthy 值,在失败时返回 falsey 值。这是一个例子:
fetch_record(0) #=> true (record #0 exists)
fetch_record(1) #=> true (record #1 exists)
fetch_record(2) #=> true (record #2 exists)
fetch_record(3) #=> nil (no record #3)
我试图找到一种优雅的方法来计算我可以用增加的参数调用fetch_record
多少次,直到它返回nil
(在上面的例子中为3次)。
到目前为止我尝试了什么
鉴于此测试目的的简化实现:
def fetch_record(index)
raise if index > 3 # just to prevent endless loops
true if index < 3
end
以下是我的尝试:
带有显式计数器变量的while
循环显然会起作用,但我看起来并非惯用:
i = 0
i += 1 while fetch_record(i)
i
#=> 3
我可以将step
和break
与显式结果值一起使用,但这看起来很麻烦:
0.step(by: 1).each { |i| break i unless fetch_record(i) }
#=> 3
懒惰的普查员更糟糕:
0.step(by: 1).lazy.map { |i| fetch_record(i) }.take_while(&:itself).count
#=> 3
有没有更简单的方法来实现上述目标?
答案 0 :(得分:10)
假设您可以反过来实施fetch_record
,则返回true
以获取不存在的记录:
def fetch_record index
index >= 3
end
(0..Float::INFINITY).detect &method(:fetch_record)
#⇒ 3
答案 1 :(得分:4)
take_while任何人?
records = 0.step.take_while{|i| fetch_record(i)}