kibernetics писал(а):Покумекаю, как обойтись без перезагрузки.
Что тут кумекать.
Есть старое множество элементов, содержащихся в списке.
Есть новое множество элементов, полученное из какого-то источника данных.
Сравниваем эти два множества, получаем в результате два списка:
1) Список элементов, которые нужно удалить из ListView.
2) Список элементов, которые нужно добавить в ListView.
А дальше удаляем пару-тройку и добавляем другую пару-тройку, не трогая тысячу тех элементов, которые не нужно трогать.
Для того, чтобы два множества можно было сравнить, вычислив разницу между ними, элементы множеств должны обладать таким качеством как идентифицируемость. Если у каждой сущности есть какой-то уникальный Id или какое-то свойство, которое можно рассматривать как Id, или несколько параметров, которые в совокупности как признак уникальности.
Если так, то оптимальный алгоритм сравнения множеств подразумевает, что составляется два списка (для двух множеств), в которых элементы упорядочены по уникальному признаку. Дальше два «указателя» устанавливаются на начала списков и начинается цикл: если элементы по указателю равны, считается, что элемент есть и в старом множестве и в новом, и с ним ничего делать не надо. В таком случае
оба указателя сдвигаются на один элемент вперёд и делается следующая итерация. Если же элементы по указателю не равны, тот указатель, который указывает на меньший элемент, сдвигается на одну позицию вперёд, но перед этим элемент, который был по сдвигаемому указателю, добавляется в один из пары новых списков (в зависимости от того, к какому изначальному списку относился сдвигаемый указатель) — такие итерации делаются до тех пор, пока тернарный (
< или
= или
>) результат сравнения элементов по указателю не сменится. Если один из указателей достиг конца списка, оставшиеся элементы из другого списка добавляются в соответствующий новый список безусловно.
На выходе имеем два новых списка: если исходные списки можно было бы обозначить как X и Y, то два новых будут содержать «список элементов, которые есть в X, но которых нет в Y» и «список элементов, которые есть в Y, но которых нет в X».
Если в реальной задачи на X был старым снапшотом ListView, а Y — новым снапшотом, то первый новый список будет списком элементов, которые надо удалить из ListView, а второй — списком элементов, которые надо добавить.
И когда я говорю «указатели» в рамках данного объяснения, это совершенно не значит, что нужно использовать указатели, дарующие доступ к произвольным участкам памяти, и которых, как считается, в VB6 в прямом и явном виде нет (хотя и их можно). Массив элементов и простая индексная переменная, хранящая индекс элемента массива, прекрасно подходят на роль списка и указателя на элемент списка.
- set_diff_algo_2.png (62.92 Кб) Просмотров: 1304