Я уверен, что это должно быть в каком-то учебнике (или, скорее всего, во всех из них), но я, кажется, использую неправильные ключевые слова для его поиска...: (
Повторяющаяся задача, с которой я сталкиваюсь во время программирования, заключается в том, что я имею дело со списками объектов из разных источников, которые мне нужно синхронизировать. Обычно существует какой-то "главный список", например. возвращаемый каким-то внешним API, а затем список объектов, которые я сам создаю, каждый из которых соответствует объекту в главном списке (подумайте "обертки" или "адаптеры" - они обычно содержат расширенную информацию о внешних объектах, специфичных для моего приложения, и/или они упрощают доступ к внешним объектам).
Жесткие характеристики всех экземпляров проблемы:
- реализация главного списка скрыта от меня; его интерфейс исправлен.
- элементы в двух списках не совместимы с назначением
- У меня есть полный контроль над исполнением списка подчиненных.
- Я не могу контролировать порядок элементов в основном списке (т.е. не сортировать)
- главный список вообще не предоставляет уведомления о добавленных или удаленных элементах или уведомление ненадежно, т.е. синхронизация может выполняться только по требованию, а не в режиме реального времени.
- просто очистка и восстановление списка подчиненных с нуля, когда это необходимо, не является вариантом:
- инициализация объектов оболочки должна считаться дорогостоящей
- другие объекты будут содержать ссылки на обертки
Дополнительные характеристики в некоторых случаях проблемы:
- Элементы
- в основном списке могут быть идентифицированы только путем чтения их свойств, а не доступа к ним напрямую по индексу или адресу памяти:
- после обновления главный список может возвращать совершенно новый набор экземпляров, даже если они все еще представляют одну и ту же информацию
- единственным интерфейсом для доступа к элементам в главном списке может быть последовательный перечислитель
- в большинстве случаев порядок элементов в главном списке стабилен, т.е. новые элементы всегда добавляются либо в начале, либо в конце, никогда не посередине; однако удаление обычно происходит в любой позиции.
Итак, как бы я обычно справлялся с этим? Какое имя алгоритма я должен Google для?
В прошлом я реализовал это различными способами (см. ниже пример), но всегда казалось, что должен быть более чистый и более эффективный способ, особенно тот, который не требует двух итераций (по одному по каждому списку).
Здесь примерный подход:
- Итерация по главному списку
- Посмотрите каждый элемент в "списке подчиненных"
- Добавить элементы, которые еще не существуют
- Как-то отслеживать элементы, которые уже существуют в обоих списках (например, помечая их или сохраняя еще один список)
- По завершении перейдите по ведомому списку и удалите все те объекты, которые не были помечены (см. 4.), и снова очистите тег от всех остальных.
Обновление 1
Спасибо за все ваши ответы! Мне нужно время, чтобы посмотреть ссылки.
[...] (текст переместился в основную часть вопроса)
Обновление 2 Перестроил средний абзац в (надеюсь) более легко анализируемые списки пули и включил детали, добавленные позже в первом обновлении.