Форум: "Начинающим";
Текущий архив: 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