在 Ruby 中循环遍历 Enumerator 的其余部分

cycle through the rest of Enumerator in Ruby

我在某个序列的中间有一个枚举器:

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

所以问题是:有没有更好的红宝石解决方案来做这件事?为什么 for 在 Ruby 中循环会这样?

在 ruby 中,强烈建议您不要使用 forwhileuntil,除非您完全清楚自己在做什么以及为什么这样做。

当需要对 Enumerable 的前两个元素做一些 special 时,我很难想象真正的问题(这可能意味着架构问题,)但是相反其中:

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 的内部结构几乎不应该被显式调用,而是使用高效和惯用的迭代、映射和归约。

为了直接回答您的问题,您当前的代码在正确的行上,但设计过度。您只需要做:

enum = (1..9).each
first = enum.next
second = enum.next

loop { puts enum.next }

一旦枚举结束,循环就会breakloop 自动为您拯救 StopIteration。如果您在循环后再次调用 enum.next ,它只会被重新引发,这不会发生在这里。

然而,正如@mudasobwa 所指出的,像这样使用枚举很平常;更常见的是使用 (1..9).each_with_index 并通过其索引明确处理第一个收益率。