Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.11.11;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.044 c
9-1163003459
DevilDevil
2006-11-08 19:30
2007.11.11
Альфаканал


15-1191917559
БарЛог
2007-10-09 12:12
2007.11.11
Direct Connect - сервер


6-1173542908
Эва
2007-03-10 19:08
2007.11.11
Обмен данными между приложениями через IdTCPClient/Server


2-1192770943
Lebedev
2007-10-19 09:15
2007.11.11
Как правильно закрыть всё приложение с модальными формами.


2-1192450912
неугомонный
2007-10-15 16:21
2007.11.11
канвас в гриде





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский