AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TListView Duplikate rückwärts löschen

Ein Thema von DieHardMan · begonnen am 17. Jun 2006 · letzter Beitrag vom 17. Jun 2006
Antwort Antwort
DieHardMan

Registriert seit: 16. Jul 2002
Ort: Stuttgart
68 Beiträge
 
#1

TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 03:14
Könnte mir jemand helfen diese Prozedur zum laufen zu bekommen? Es soll von allen doppelten Einträgen immer nur das unterste Item übrigbleiben. Hab schon länger rumprobiert bekomm aber immer nen "out of bounds" Fehler, sollte wohl andersrum anfangen also bei lv.items.count - 1 und vielleicht wär ne for schleife auch besser aber irgendwie krieg ichs grad net hin.

Delphi-Quellcode:
procedure DeleteFirstDoubles(lv: TListView; SubItem: integer = -1);
var
  li1 : TListItem;
  li2 : TListItem;

  x : integer;
  y : integer;

begin
  if lv.Items.Count < 1 then Exit;

  x := 0;

  while x <= lv.Items.Count - 1 do
    begin
      li1 := lv.Items[x];

      y := x + 1;
      while y <= lv.Items.Count - 1 do
        begin
          li2 := lv.Items[y];

          if SubItem > -1 then
            begin
              if AnsiSameText(li1.SubItems[SubItem], li2.SubItems[SubItem]) then
                li1.Delete;
            end
          else
            begin
              if AnsiSameText(li1.Caption, li2.Caption) then
                li1.Delete;
            end;
          inc(y);
        end;

      inc(x);
    end;
end;
Alle meine Entchen...
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#2

Re: TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 04:04
ich habs mal so geändert, dass es funktioniert (ansiCompareText nur, weil AnsiSameText in D3 nicht existiert)

das ganze ist jetzt rückwärts...

Delphi-Quellcode:
procedure DeleteFirstDoubles(lv: TListView; SubItem: integer);
var
  li1,li2: TListItem;
  x,y : integer;
begin
  if lv.Items.Count < 1 then Exit;
  x := lv.Items.Count - 1;
  while x >= 1 do
  begin
    li1 := lv.Items[x];
    y := x - 1;
    while y >= 0 do
    begin
      li2 := lv.Items[y];
      if SubItem > -1 then
      begin
        if AnsiCompareText(li1.SubItems[SubItem], li2.SubItems[SubItem])=0 then
          li2.Delete;
      end else
      begin
        if AnsiCompareText(li1.Caption, li2.Caption)=0 then
          li2.Delete;
      end;
      dec(y);
    end;
    dec(x);
  end;
end;
Gruß Frank
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#3

Re: TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 10:04
Guten Morgen,

hier noch eine tageslichttaugliche Alternative:

Delphi-Quellcode:
procedure RemoveDuplicates(items: TListItems; index: Integer);
var
  i: Integer;
  isEqual: Boolean;
begin
  items.BeginUpdate;
  for i := Pred(items.Count) downto 1 do
  begin
    if index < 0
      then isEqual := AnsiSameText(items[Pred(i)].Caption, items[i].Caption)
      else isEqual := AnsiSameText(items[Pred(i)].Subitems[index], items[i].Subitems[index]);
    if isEqual then
      items[Pred(i)].Delete;
  end;
  items.EndUpdate;
end;
Grüße vom marabu
  Mit Zitat antworten Zitat
DieHardMan

Registriert seit: 16. Jul 2002
Ort: Stuttgart
68 Beiträge
 
#4

Re: TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 13:08
@marabu, dein Code funktioniert zwar, vergleicht aber nur die aufeinanderfolgenden Items auf Gleichheit und nicht alle, dazu sind 2 Schleifen nötig.

@frank, funktioniert solange bis die Prozedur versucht auf Items zuzugreifen die es soeben gelöscht hat, dann kommt ne EAccessViolation. Man müsste da noch prüfen ob das Item existiert und den Durchlauf überspringen.
Alle meine Entchen...
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#5

Re: TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 13:53
Hier ist noch eine Variante:

Delphi-Quellcode:
procedure RemoveDuplicates (Items: TListItems; Index: Integer = -1);
  var i : Integer;
      s : string;
      L : TStrings;
begin
  L := TStringList.Create;
  for i := Items.Count - 1 downto 0 do
    begin
      if (Index < 0) then
        s := Items[i].Caption
      else
        s := Items[i].SubItems[Index];
      if (L.IndexOf(s) < 0) then
        L.Add(s)
      else
        Items[i].Delete;
    end;
  L.Free;
end;
Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#6

Re: TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 14:25
Zitat von DieHardMan:
@frank, funktioniert solange bis die Prozedur versucht auf Items zuzugreifen die es soeben gelöscht hat, dann kommt ne EAccessViolation. Man müsste da noch prüfen ob das Item existiert und den Durchlauf überspringen.
also den Fall hatte ich nicht gehabt, bei welcher konstellatio tritt der auf? Weil ich lösche item li2 (y) und das ist beim nächsten durchlauf schon eins weiter oben...somit sollte kein AV kommen

Gruß Frank
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#7

Re: TListView Duplikate rückwärts löschen

  Alt 17. Jun 2006, 14:38
Zitat von DieHardMan:
@marabu, dein Code funktioniert zwar, vergleicht aber nur die aufeinanderfolgenden Items auf Gleichheit und nicht alle, dazu sind 2 Schleifen nötig.
Das ist richtig. Ich ging von einer sortierten Liste aus - vielleicht weil du deine Anforderung nicht in den Text geschrieben hattest. Bei unsortierten Items sollte man eine getrennte Liste führen, die dann aber sortiert sein sollte. Du kommst dann am Ende automatisch auf den Ansatz, den Hawkeye gezeigt hat - nur fehlt dort noch die Einstellung Sorted für die TStringList.

marabu
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz