Будет ли array.each работать правильно, если массив обновляется во время каждой итерации? - PullRequest
2 голосов
/ 24 февраля 2011

Будет ли метод правильно обрабатывать каждый элемент массива, если массив обновляется в блоке кода каждого цикла?

Например:

arr.each do |x|
  if (x != 2)
    arr.push(x+4)
  end
end

Будет ли цикл повторяться по каждому элементу массива, даже если он удлиняется?

Ответы [ 2 ]

4 голосов
/ 24 февраля 2011

Может быть


Да , если вы говорите о МРТ , и вопрос: " Пройдет ли итератор мои новые элементы? ".

Если вы говорите о Ruby как о языке, " возможно ".Спецификации не существует, поэтому MRI служит эталонной реализацией.

Но, сказав, что это просто кажется чем-то, что будет зависеть от реализации, отчасти потому, что требование какого-либо конкретного поведения наложит ограничение на реализации без ясностивыгоды, но с определенными компромиссами производительности.

Это также весьма императив , , так что это, возможно, не "путь Руби", которыйбольше склоняется к функциональным стилям .

Вот как я думаю, что хорошая программа на Ruby должна писать такой цикл.Это выражение будет возвращать старый массив a до тех пор, пока он не изменится, и в этом случае он создаст новый массив в функциональном стиле, чтобы никогда не возникало никаких сомнений относительно того, каким будет результат ...

>> a = [1, 2, 3]
=> [1, 2, 3]
>> a.inject(a) { |m, e| e < 99 ? m + [99] : m }
=> [1, 2, 3, 99, 99, 99]

A быстрее(если будет добавлено много новых элементов) полуфункциональное выражение будет:

t = a.inject(a.dup) { |m, e| e < 99 ? m << 99 : m } 
0 голосов
/ 24 февраля 2011

Да, он будет продолжать цикл до тех пор, пока не достигнет конца массива, что, вероятно, никогда не произойдет, поскольку он продолжает получать новые записи с каждой итерацией.

Так что я настоятельно рекомендую против вас текущий код, поскольку вы, вероятно, застряли в бесконечном цикле.

Не знаю точно, для чего вы собираетесь, однако этот код будет намного лучше, так как имеет четкое окончание:

arr.each do |x|
  if x < 2
    arr.push x + 4
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...