![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Listview повторы
hT9 © (2007-10-21 11:15:00)Привет. Вообщем нужно из LV удалить повторные строки ( по subitems[1].
Использую такую функцию .
for i := pp.Items.Count-1 downto 1 do
begin
s1 := pp.Items[i].SubItems[1];
for j := i-1 downto 0 do
begin
s1:= pp.Items[i].SubItems[1]+pp.Items[i].SubItems[0];
s2 := pp.Items[j].SubItems[1]+pp.Items[j].SubItems[0];
if ( s1 =pp.Items[i].SubItems[1]+pp.Items[i].SubItems[0] ) and ( s1 = s2 ) then
begin
pp.Items.Delete( i );
Break;
end;
end;
end;
Все хорошо пока строк в LV меньше 500 . А вот когда их там тысячи 3 , то тогда программа "зависает" на время выполнения кода .
application.ProcessMessages;
Особого эффекта не дает + увеличивается время выполнения .
Есть способ как побыстрее убрать повторы ?
vpbar (2007-10-21 15:36:00) [1]Во-первых, разделите данные и их представления. В данном случае можно сделать виртуальный список (listview.OwnerData=true). И данные брать из списка тогоже ЕStringList, если кроме имени там ничего не нужно.
Во-вторых, по поводу удаления дубликатов. Быстрее всего отсортировать список ( O(n log2 n)- если быстрой сортировкой) и затем пройтись один раз по списку удаляя элемент,если предидущий такой же. Или копируя в новый список только первый элемент а следующий не копировать если он такой же.
hT9 (2007-10-21 12:40:00) [2]
> В Subitems[5] - Альбом
не в [5] а в [1]
hT9 (2007-10-21 12:39:00) [3]
> а на этапе добавлениия сортировать не получится?
Вообщем смотри для чего мне это надо .
Пишу проигрыватель . LV - это плейлист . Придобавлении я сортирую по
Subitems[5] ( там путь до файла , если такой есть , я не добавляю ).
В Subitems[0] - Исполнитель
В Subitems[5] - Альбом
Соответственно удаляю все повторные альбомы одного исполнителя . И вывожу
сколько у меня разных альбомов .
DVM (2007-10-21 12:36:00) [4]да и вообще не добавлять дубликаты
DVM (2007-10-21 12:36:00) [5]
> hT9 (21.10.07 12:34) [14]
а на этапе добавлениия сортировать не получится?
DVM (2007-10-21 12:35:00) [6]
> Jump (21.10.07 12:29) [12]
сортировать можно и в ListView (хотя, наверное чуть медленнее)
hT9 (2007-10-21 12:34:00) [7]
> 1. А давай ты просто за один проход загрузишь названия (или
> что там у тебя за строки, те, которые s1 и s2) в StringList,
> и ссылки на Item туда же.
> 2. Потом отсортируешь StringList.Sort.
> 3. Потом еще одним проходом пройдешь по StringList, и удалишь
> те дубликаты, которые тебе не нравятся.
Я думал про StringList , когда искал способ ускорить мою процедуру. Но мне кажется , что с ним дольше будет .
DVM (2007-10-21 12:33:00) [8]
> F190 (21.10.07 12:28) [11]
тут вот какая ерунда с этим вариантом.
Допустим у нас совпадает 100 элемент 5 и 10. При этом мы удалим 100 наткнувшись при переборе на 10, но 10 так и останется в списке. Он будет удален, когда во внешнем цикле мы дойдем до 10 и сравним его с 5-ым.
Нехорошо как-то. Лишние телодвижения.
Наверное, предварительная сортировака ускорит дальнейшее удаление, зотя и сама займет изрядно времени.
Jump (2007-10-21 12:29:00) [9]1. А давай ты просто за один проход загрузишь названия (или что там у тебя за строки, те, которые s1 и s2) в StringList, и ссылки на Item туда же.
2. Потом отсортируешь StringList.Sort.
3. Потом еще одним проходом пройдешь по StringList, и удалишь те дубликаты, которые тебе не нравятся.
F190 (2007-10-21 12:28:00) [10]Спасибо !!! Работает действительно быстрее .
DVM (2007-10-21 12:06:00) [11]если я нигде не ошибся, то мой вариант в 3 раза быстрее твоего
DVM (2007-10-21 11:59:00) [12]Вроде так, но можно еще оптимизировать.
procedure TForm1.Button1Click(Sender: TObject);
var
i, j: integer;
begin
TimeReset;
pp.Items.BeginUpdate;
try
for i := pp.Items.Count - 1 downto 1 do
for j := i - 1 downto 0 do
if AnsiCompareStr(pp.Items[i].SubItems[0], pp.Items[j].SubItems[0])=0 then
if AnsiCompareStr(pp.Items[i].SubItems[1], pp.Items[j].SubItems[1])=0 then
begin
pp.Items.Delete(i);
Break;
end;
finally
pp.Items.EndUpdate;
end;
Caption := TimeStrMks;
end;
hT9 (2007-10-21 11:43:00) [13]Русские буквы в названиях есть .
hT9 (2007-10-21 11:43:00) [14]
> в в списке может быть три и больше совпадающих строк?
Да может . Их может хоть 20 и 30 быть одинаковых .
> Сравнение с учетом регистра или нет? Русские буквы в названиях
> есть?
Сравнение идет с учетом регистра .
DVM (2007-10-21 11:39:00) [15]Сравнение с учетом регистра или нет? Русские буквы в названиях есть?
DVM (2007-10-21 11:37:00) [16]в в списке может быть три и больше совпадающих строк?
hT9 (2007-10-21 11:33:00) [17]Сорри . Не дозадал вопрос .
Убрать повторы из строк , в которых SubItems[1] и [0] одинаковы .
DVM (2007-10-21 11:31:00) [18]s1:= pp.Items[i].SubItems[1]+pp.Items[i].SubItems[0];
s2 := pp.Items[j].SubItems[1]+pp.Items[j].SubItems[0];
эти присваивания тоже можно вообще убрать:
DVM (2007-10-21 11:24:00) [19]
> if ( s1 =pp.Items[i].SubItems[1]+pp.Items[i].SubItems[0]
> )
это зачем?
DVM (2007-10-21 11:21:00) [20]
> Есть способ как побыстрее убрать повторы ?
Ну первое, что приходит в голову
listview1.Items.BeginUpdate;
... удаляем ....
listview1.Items.EndUpdate;