Изящный способ остановки в конце счетчика?

Есть ли изящный способ понять, кто находится в конце счетчика?

Например,

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

Конечно, e вызывает StopIteration, когда вы достигаете конца перечислителя.

Есть ли хороший способ вырваться из цикла while без помощи? Я знаю, что могу просто сказать e.each (или вообще не использовать перечислитель), но для моей конкретной задачи я хочу сделать что-то особенное для первых нескольких итераций, а затем что-то общее для последних нескольких.

Я хочу посмотреть на следующее значение и получить nil вместо ошибки.

Какие-нибудь советы? Там, наверное, что-то очевидное, что я скучаю...

NB. Мне не нужно использовать счетчики, но это кажется самым простым способом решения моей проблемы. Так что если у вас есть не перечислимое решение (для итерации перечислимого), не стесняйтесь поделиться. (на этой ноте, может быть, я должен просто использовать each или each_with_index и использовать счетчик для особых случаев...)

2 ответа

Решение

Спасая от StopIteration это способ сделать это. И единственный способ.*

Когда вы понимаете, что любое значение (например, nil, как вы предлагаете) возвращается next может быть следующим значением перечислимого, становится ясно, что для него невозможно вернуть значение в особом случае, так как тогда оно никогда не может быть в перечисляемом. Вот почему next должен поднять StopIteration когда закончите вместо того, чтобы делать что-то более "изящное".

* Предполагая, что вы должны использовать Enumerator , поскольку, возможно, есть лучший способ решить вашу реальную проблему без этого.

Что не так с использованием each_with_index как вы предлагаете иметь особое поведение для первого N? Этот шаблон появляется все время:

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

В Enumerable есть множество инструментов, которые вы можете использовать.

Другие вопросы по тегам