简体   繁体   English

以优雅的方式在枚举数结尾处停止?

[英]Graceful way of stopping at the end of an enumerator?

Is there a graceful way of realizing one is at the end of an enumerator? 在枚举器的末尾是否有一种优雅的实现方式?

For instance, 例如,

a = (1..10).to_a
e = a.each
e.next # should yield 1
while e.next
  # do something
end

Of course, e raises StopIteration when you get to the end of the enumerator. 当然,当您到达枚举数的末尾时,e会引发StopIteration

Is there a nice way of breaking out of that while loop without a rescue? 是否有一种无需救援就可以打破while循环的好方法? I know that I can just say e.each (or just not use the enumerator at all), but for my specific problem I want to do something special for the first few iterations and then something general for the last few. 我知道我只能说e.each(或者根本不使用枚举器),但是对于我的特定问题,我想对前几次迭代做一些特别的事情,然后对后几次进行一些通用的事情。

I want a way of looking at the next value and getting nil instead of an error. 我想要一种查看下一个值并获取nil而不是错误的方法。

Any tips? 有小费吗? There's probably something obvious that I'm missing... 可能有些明显的我想念了...

NB. 注意 I don't have to use enumerators, but it seems like the easiest way to solve my problem. 我不必使用枚举器,但这似乎是解决我的问题的最简单方法。 So if you have a non enumerator solution (for iterating through an enumerable), feel free to share. 因此,如果您有非枚举器解决方案(用于遍历枚举),请随时共享。 (on that note, maybe I should just use each or each_with_index and use the counter for the special cases...) (在此说明上,也许我应该只使用each或each_with_index并将计数器用于特殊情况...)

Rescuing from StopIteration is the way to do it. StopIteration抢救是做到这一点方法。 And the only way.* 而且是唯一的方法。*

When you realize that any value (eg nil , as you suggest) returned by next could be the next value of the enumerable, it becomes clear that it's not possible for it to return a special-case value, since that could then never be in the enumerable. 当您意识到next所返回的任何值(如您所建议的nil )都可能是可枚举的下一个值时,很明显,它不可能返回特殊情况的值,因为那样就永远不可能不可计数的。 This is why next must raise StopIteration when complete instead of doing something more "graceful". 这就是为什么next必须在完成时提高StopIteration ,而不是做一些更“优雅”的事情。

* Assuming you must use Enumerator , as there's probably a better way to solve your real problem without doing so. * 假设您必须使用Enumerator ,因为可能有一种更好的解决实际问题的方法,而无需这样做。

What's wrong with using each_with_index like you suggest to have special behavior for the first N? 像您建议对前N个使用特殊行为那样,使用each_with_index有什么问题? This pattern shows up all the time: 此模式一直显示:

a.each_with_index do |e, i|
  if (i <= n)
    # Do special stuff
  end
  # Do regular stuff
end

There's a lot of tools in the Enumerable toolbox you can make use of. 您可以使用Enumerable工具箱中的许多工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM