Удаление элементов из массива требует нескольких проходов, чтобы удалить их все - PullRequest
12 голосов
/ 11 апреля 2011

У меня есть массив из ~ 1200 объектов ruby, и я хочу зациклить их и удалить объекты с именами, которые содержат слова или части слов.

Итак, я попробовал это:

list.each do |item|
  if item.name =~ /cat|dog|rat/i
    puts item.name
    list.delete(item)
  end
end

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

Почему в мире это происходит?

Ответы [ 2 ]

23 голосов
/ 11 апреля 2011

Это вы изменяете базовую коллекцию, перебирая ее.
По сути, если коллекция каким-либо образом изменяется во время итерации (становится пустой, добавляется новый элемент и т. Д.), Итератор не имеет много способов справиться с этим.

Попробуйте отклонить .

list.reject! {|item| item.name =~ /cat|dog|rat/i }
0 голосов
/ 29 января 2016

Но есть и другой способ сделать то же самое, что и reject! с delete:

list.delete_if { |item| item =~  /cat|dog|rat/i }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...