[Ruby] Вопрос по итераторам
Dennis Vshivkov
walrus на amur.ru
Пт Дек 3 17:33:58 MSK 2004
On Fri, Dec 03, 2004 at 11:55:53AM +0200, Kravchenko Sergey wrote:
>>> Не подскажите ли - есть ли возможность внутри цикла итератора
>>> перейти к следующему значению итерации не возвращаясь в начало
>>> цикла? То есть, например, итерация
>>> [ 1, "a", 2, "b", 3, "c" ].each{ |i|
>>> ...
>>> ### get next iteration
>>> ...
>>> puts (i)
>>> }
>>> выдавала следующую последовательность:
>>> "a"
>>> "b"
>>> "c"
>> next
>> это аналог continue в C/C++
>> работает в циклах while и в итерациях
>> [ 1, "a", 2, "b", 3, "c" ].each{ |i|
>> next if i.kind_of? Fixnum
>> puts (i)
>> }
> Спасибо за ответ, но вариант с next мне не подходит.
> Как я уже сказал, необходимо перейти к следующему значению итерации,
> _не возвращаясь в начало цикла_
> Насколько я понимаю, такая возможность должна быть предусмотрена в самом
> интерпретаторе, но подобной команды я в описании языка не нашёл - возможно,
> она всё-таки не предусмотрена. Если это действительно так - хотелось бы
> узнать мнение народа по этому поводу. Может быть есть какой-нибудь способ
> сделать это красиво? ;)
> Вот другой (более точный) пример задачи:
> output = Array.new
> [ "a", "b", "b1", "b2", "c", "d" ].each{|i|
> output = [ i ]
> if i == "b"
> ### получить все следующие элементы итерации,
> ### начинающиеся с буквы "b" (т.е. "b1", "b2")
> ### и записать их в массив output
> end
> puts output.join( " " )
> }
Этот пример не полностью соответствует первой формулировке. Потому
что нельзя проверить значение следующего элемента, не получив его. Ну,
это детали.
> результатом должен быть следующий выход:
> "a"
> "b b1 b2"
> "c"
> "d"
Только без кавычек, видимо...
> Надеюсь теперь задача более понятна.
Ну вот, например. Видимость отсутствия перехода в начало цикла. Не знаю,
насколько это красиво... :)
#!/usr/bin/ruby
out = []
%w(a b b1 b2 c d).inject(false) { |skip, i|
out.clear unless skip
if i == 'b' || !out.empty? && i[0] == ?b
out.push i
next true
end
unless out.empty?
# out готов
puts out.join(' ')
out.clear
end
out.push i
# out готов
puts out.push(i).join(' ')
}
Идея понятна, я надеюсь. По-честному отсутствие возврата в начало
цикла можно замутить на Continuation. Но это будет ещё `красивей'. :)
--
/Awesome Walrus <walrus на amur.ru>
P.S. Кука в тему. =)
...Выполняя трудную задачу, не томиться этим -- это лекарство...
Подробная информация о списке рассылки Ruby