我在某个序列的中间有一个枚举器:
enum = (1..9).each
first = enum.next
second = enum.next
现在我想循环完成序列的其余部分(3..9个数字)。但是看似明显的解决方案(例如在python中工作),从序列的开头而不是第三个项重新开始:
for item in enum
puts item
end
# prints 1..9 instead of 3..9
我找到的工作解决方案看起来很难看:
begin
while item=enum.next
puts item
end
rescue StopIteration
end
所以问题是:有没有更好的红宝石解决方案来做这件事?为什么Ruby中的for
循环以这种方式运行?
答案 0 :(得分:5)
要直接回答您的问题,您当前的代码是正确的,但过度设计。你只需要这样做:
enum = (1..9).each
first = enum.next
second = enum.next
loop { puts enum.next }
枚举到达终点时,循环将break
; loop
为您自动救出StopIteration
。如果您在循环之后再次呼叫enum.next
,则只会重新提升,而这在此处不会发生。
然而正如@mudasobwa指出的那样,使用这样的枚举非常通常;更常见的是使用(1..9).each_with_index
并通过其索引显式处理第一个收益率。
答案 1 :(得分:3)
在红宝石中,强烈建议您不要使用for
,while
和until
,除非您完全了解自己的行为和原因。
当我需要在Enumerable
的前两个元素上做一些特殊时,我很难想象真正的问题(这可能意味着一个架构问题),而不是这个:
enum.next
enum.next
loop do
begin
puts enum.next
rescue StopIteration
break
end
end
那里不需要 更新: rescue
,请参阅@ TomLord的回答澄清。
你最好这样做:
enum.with_index do |element, idx|
print "First " if idx == 0
print "Second " if idx == 1
puts element
end
Iterator
的内部几乎从不应该被明确调用,使用高效和惯用的迭代,映射和减少。