Перебирать массив при добавлении новых элементов в массив - PullRequest
1 голос
/ 09 ноября 2019

Я пишу сценарий очистки веб-страниц в Ruby, который открывает веб-сайт подержанной машины, ищет марку / модель автомобиля, просматривает страницы результатов и затем просматривает данные на каждой странице.

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

Я определил cleanpages как массив и заполнил его, насколько мне известно, доступными страницами при первом открытии сайта. Затем я использую cleanpages.each do для перебора этих «страниц». Каждый раз, когда я нахожусь на новой странице, я добавляю все известные страницы обратно в cleanpages и затем запускаю cleanpages.uniq, чтобы удалить дубликаты. Кажется, проблема в том, что cleanpages.each do повторяется только столько раз, сколько его исходная длина.

Можно ли сделать так, чтобы в цикле each do я увеличивал количество повторений, которое он будет повторять?

1 Ответ

4 голосов
/ 09 ноября 2019

Вместо того, чтобы использовать Array # каждый, попробуйте использовать ваш массив в качестве очереди. Общая идея такова:

queue = initial_pages
while queue.any?
  page = queue.shift
  new_pages = process(page)
  queue.concat(get_unprocessed_pages(new_pages))
end

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

Вы должны быть уверены, что удалили страницы из new_pages, которые уже находятся в очереди или уже были обработаны.

Вы также можете сделать это, просто сохраняя структуру данных массива, но вручную сохраняя указатель на текущий элемент в вашем списке. Преимуществом этого является сохранение полного списка «просмотренных» страниц, так что вы можете удалить их из списка new_pages перед добавлением всего, что осталось в списке:

index = 0
queue = initial_pages
while true do
  page = queue[index]
  break if page.nil?
  index += 1
  new_pages = get_new_pages(page) - queue
  queue.concat(new_pages)
end
...