Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.11.11;
Скачать: CL | DM;

Вниз

Listview повторы   Найти похожие ветки 

 
hT9   (2007-10-21 11:15) [0]

Привет. Вообщем нужно из 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;
Особого эффекта не дает + увеличивается время выполнения .
Есть способ как побыстрее убрать повторы ?


 
DVM ©   (2007-10-21 11:21) [1]


> Есть способ как побыстрее убрать повторы ?

Ну первое, что приходит в голову

listview1.Items.BeginUpdate;
... удаляем ....
listview1.Items.EndUpdate;


 
DVM ©   (2007-10-21 11:24) [2]


> if ( s1 =pp.Items[i].SubItems[1]+pp.Items[i].SubItems[0]
> )

это зачем?


 
DVM ©   (2007-10-21 11:31) [3]

s1:=  pp.Items[i].SubItems[1]+pp.Items[i].SubItems[0];
s2 := pp.Items[j].SubItems[1]+pp.Items[j].SubItems[0];

эти присваивания тоже можно вообще убрать:


 
hT9   (2007-10-21 11:33) [4]

Сорри . Не дозадал вопрос .

Убрать повторы  из строк , в которых SubItems[1] и [0] одинаковы  .


 
DVM ©   (2007-10-21 11:37) [5]

в в списке может быть три и больше совпадающих строк?


 
DVM ©   (2007-10-21 11:39) [6]

Сравнение с учетом регистра или нет? Русские буквы в названиях есть?


 
hT9   (2007-10-21 11:43) [7]


> в в списке может быть три и больше совпадающих строк?

Да может . Их может хоть 20 и 30 быть одинаковых .

> Сравнение с учетом регистра или нет? Русские буквы в названиях
> есть?

Сравнение идет с учетом регистра .


 
hT9   (2007-10-21 11:43) [8]

Русские буквы в названиях есть .


 
DVM ©   (2007-10-21 11:59) [9]

Вроде так, но можно еще оптимизировать.


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;


 
DVM ©   (2007-10-21 12:06) [10]

если я нигде не ошибся, то мой вариант в 3 раза быстрее твоего


 
F190   (2007-10-21 12:28) [11]

Спасибо !!! Работает действительно быстрее .


 
Jump   (2007-10-21 12:29) [12]

1. А давай ты просто за один проход загрузишь названия (или что там у тебя за строки, те, которые s1 и s2) в StringList, и ссылки на Item туда же.
2. Потом отсортируешь StringList.Sort.
3. Потом еще одним проходом пройдешь по StringList, и удалишь те дубликаты, которые тебе не нравятся.


 
DVM ©   (2007-10-21 12:33) [13]


> F190   (21.10.07 12:28) [11]

тут вот какая ерунда с этим вариантом.

Допустим у нас совпадает 100 элемент 5 и 10. При этом мы удалим 100 наткнувшись при переборе на 10, но 10 так и останется в списке. Он будет удален, когда во внешнем цикле мы дойдем до 10 и сравним его с 5-ым.
Нехорошо как-то. Лишние телодвижения.

Наверное, предварительная сортировака ускорит дальнейшее удаление, зотя и сама займет изрядно времени.


 
hT9   (2007-10-21 12:34) [14]


> 1. А давай ты просто за один проход загрузишь названия (или
> что там у тебя за строки, те, которые s1 и s2) в StringList,
>  и ссылки на Item туда же.
> 2. Потом отсортируешь StringList.Sort.
> 3. Потом еще одним проходом пройдешь по StringList, и удалишь
> те дубликаты, которые тебе не нравятся.

Я думал про StringList , когда искал способ ускорить мою процедуру. Но мне кажется , что с ним дольше будет .


 
DVM ©   (2007-10-21 12:35) [15]


> Jump   (21.10.07 12:29) [12]

сортировать можно и в ListView (хотя, наверное чуть медленнее)


 
DVM ©   (2007-10-21 12:36) [16]


> hT9   (21.10.07 12:34) [14]

а на этапе добавлениия сортировать не получится?


 
DVM ©   (2007-10-21 12:36) [17]

да и вообще не добавлять дубликаты


 
hT9   (2007-10-21 12:39) [18]


> а на этапе добавлениия сортировать не получится?

Вообщем смотри для чего мне это надо .

Пишу проигрыватель . LV - это плейлист . Придобавлении я сортирую по
Subitems[5] ( там путь до файла , если такой есть , я не добавляю ).
В Subitems[0] - Исполнитель
В Subitems[5] - Альбом
Соответственно удаляю все повторные альбомы одного исполнителя . И вывожу
сколько у меня разных альбомов .


 
hT9   (2007-10-21 12:40) [19]


> В Subitems[5] - Альбом

не в [5] а в [1]


 
vpbar ©   (2007-10-21 15:36) [20]

Во-первых, разделите данные и их представления. В данном случае можно сделать виртуальный список (listview.OwnerData=true). И данные брать из списка тогоже ЕStringList, если кроме имени там ничего не нужно.

Во-вторых, по поводу удаления дубликатов. Быстрее всего отсортировать список ( O(n log2 n)- если быстрой сортировкой) и затем пройтись один раз по списку удаляя  элемент,если предидущий такой же. Или копируя в новый список только первый элемент а следующий не копировать если он такой же.



Страницы: 1 вся ветка

Текущий архив: 2007.11.11;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.026 c
15-1191818370
MultIfleX
2007-10-08 08:39
2007.11.11
реализация RSA


15-1191690459
mike-d
2007-10-06 21:07
2007.11.11
easy - с Днем рождения!


2-1192790942
Shakesbeer
2007-10-19 14:49
2007.11.11
Работа с com-портом.


2-1192797770
Neo
2007-10-19 16:42
2007.11.11
поиск топ100


15-1191796932
Альберт Мобайл
2007-10-08 02:42
2007.11.11
посоветуйте