Delphi-Version: 2010
Delete duplicates from list
Delphi-Quellcode:
...but nothing happen after this. List is TStrings. F1 :(
var
S: string; I: Integer; begin for S in List do begin I := List.IndexOf(S); while I = -1 do begin List.Delete(I); I := List.IndexOf(S); end; end; end; |
AW: Delete duplicates from list
.. could it be that I has never value -1
because S is in the List and you will get for I the position in the List of S.
Delphi-Quellcode:
edit:
for S in List do
begin I := List.IndexOf(S); while I = -1 do begin List.Delete(I); I := List.IndexOf(S); end; end; If you want to use TStringList there is an property called duplicates This can be set to avoid duplicate entries in the list. Best regards Klaus |
AW: Delete duplicates from list
Delphi-Quellcode:
Or use a TStringlist as Klaus said before (this TStringlist must have set Sorted to true).
var
S: string; I, J: Integer; begin for S in List do begin I := List.IndexOf(S); for J := List.Count - 1 downto I + 1 do if List[J] = S then List.Delete(J); end; end; |
Re: Delete duplicates from list
I found example for TStringList:
Code:
but, first is for TStringList - I need for TStrings - it's component property, and second uses sorting and data order is important, so I can't sort it. Thanks for help, guys :D
http://delphi.about.com/od/delphitips2009/qt/remove-duplicat.htm
|
AW: Delete duplicates from list
Delphi-Quellcode:
not tested.
sList := TStringList.create;
try sList.sorted := true; sList.duplicates := dupIgnore; sList.assign(List); List.assign(sList); finally sList.free; end; Best regards Klaus |
AW: Delete duplicates from list
Alternative:
Delphi-Quellcode:
procedure RemoveDoubles(Strings: TStrings);
var I, J: integer; begin Strings.BeginUpdate; I:= 0; while I <= Strings.Count-2 do begin J:= I+1; while J <= Strings.Count-1 do begin if Strings[I] = Strings[J] then begin Strings.Delete(J); Dec(J); end; Inc(J); end; Inc(I); end; Strings.EndUpdate; end; procedure TForm1.Button1Click(Sender: TObject); begin RemoveDoubles(Memo1.Lines); end; |
AW: Delete duplicates from list
Da finde ich meinen Vorschlag aber übersichtlicher (nix für ungut).
|
AW: Delete duplicates from list
Schneller (ohne Sort):
Delphi-Quellcode:
@DeddyH:
For i := List.Count - 1 downto 0 do
For j := List.Count - 1 downto i + 1 do If s[i]=s[j] then s.delete(j);
Delphi-Quellcode:
entspricht doch
for S in List do I := List.IndexOf(S);
Delphi-Quellcode:
, nur das Letzteres um eine Größenordnung performanter ist oder irre ich mich?
For i := 0 to List.Count-1 do S := List[i];
|
AW: Delete duplicates from list
Das mag schon sein, ein wenig C&P sei mir doch gegönnt.
|
AW: Delete duplicates from list
Ohne Quellenangabe? :mrgreen:
|
AW: Delete duplicates from list
^^ Ich habe das jetzt nochmal ins Reine geschrieben und versucht, dabei möglichst simpel zu bleiben.
Delphi-Quellcode:
Wer mag, kann auch auf StrUtils u.a. zurückgreifen, so sollte es aber schon funktionieren.
procedure DeleteDuplicates(const List: TStrings);
var CurrentIndex, FollowingIndex: integer; begin Assert(Assigned(List)); List.BeginUpdate; try CurrentIndex := 0; while CurrentIndex < List.Count - 1 do begin for FollowingIndex := List.Count - 1 downto CurrentIndex + 1 do if List[CurrentIndex] = List[FollowingIndex] then List.Delete(FollowingIndex); Inc(CurrentIndex); end; finally List.EndUpdate; end; end; procedure DeleteDuplicatesCaseInsensitive(const List: TStrings); var CurrentIndex, FollowingIndex: integer; begin Assert(Assigned(List)); List.BeginUpdate; try CurrentIndex := 0; while CurrentIndex < List.Count - 1 do begin for FollowingIndex := List.Count - 1 downto CurrentIndex + 1 do if AnsiLowerCase(List[CurrentIndex]) = AnsiLowerCase(List[FollowingIndex]) then List.Delete(FollowingIndex); Inc(CurrentIndex); end; finally List.EndUpdate; end; end; |
AW: Delete duplicates from list
Die äussere For-Schleife hat aber mehr Durchläufe als nötig.
Ich würde da eine While-Schleife verwenden, die dann abbricht wenn es nichts mehr zu tun gibt. Ungetestet:
Delphi-Quellcode:
Hätte die Stringliste z.B. 1000 identische Einträge würde die While-Schleife schon nach einem Durchlauf abbrechen, während eine For-Schleife alle restlichen 999 Einträge erfolglos durchtesten würde.
CurrentIndex := 0
while CurrentIndex < List.Count - 1 do begin for FollowingIndex := List.Count - 1 downto CurrentIndex + 1 do if List[CurrentIndex] = List[FollowingIndex] then List.Delete(FollowingIndex); Inc(CurrentIndex); end; |
AW: Delete duplicates from list
Stimmt, ich hatte vergessen, dass for die Anzahl nur einmalig ermittelt.
[edit] Korrigiert [/edit] |
AW: Delete duplicates from list
Das selbst in soetwas scheinbar banalem der Teufel (nun ja, ein Teufelchen) im Detail stecken kann...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:35 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