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