AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi TStringList ignoriert doppelte Einträge nicht
Thema durchsuchen
Ansicht
Themen-Optionen

TStringList ignoriert doppelte Einträge nicht

Offene Frage von "himitsu"
Ein Thema von DevidEspenschied · begonnen am 6. Sep 2010 · letzter Beitrag vom 6. Sep 2010
Antwort Antwort
DevidEspenschied

Registriert seit: 7. Sep 2006
Ort: Berlin
441 Beiträge
 
Delphi 12 Athens
 
#1

TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 18:34
Delphi-Version: 2007
Hi,

ich benutze Delphi 2007 Pro und versuche, eine StringList mit Einträgen zu füllen. Dabei sollen doppelt hinzugefügte Einträge ignoriert werden. Hier ein vereinfachter Auszug meines Codes:

Delphi-Quellcode:
var Liste : TStringList
    i : Byte;
begin
  Liste:=TStringList.Create;
  
  Liste.Sorted:=False;
  Liste.Duplicates:=dupIgnore;

  Liste.Add('Eintrag 1');
  Liste.Add('Eintrag 1');
  Liste.Add('Eintrag 1');

  for i:=0 to Liste.Count-1 do showmessage(Liste.Strings[i]);

  Liste.Free;
end;
Woran kann es liegen, dass die doppelten Einträge trotzdem vorhanden sind?
Devid
Devid Espenschied
Pre-sales Consultant
Embarcadero Germany GmbH
germany.info@embarcadero.com

Kein Support per PN
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 18:38
Delphi-Quellcode:
Liste.Sorted:=False;
Liste.Duplicates:=dupIgnore;
Woran kann es liegen, dass die doppelten Einträge trotzdem vorhanden sind?
Auszug aus der Hilfe:
Zitat:
Note: Duplicates does nothing if the list is not sorted.
Edit: Und zukünftig daran denken, Ressourcen-Schutzblöcke zu nutzen, damit auch im Fehlerfall der Speicher freigegeben wird:
Delphi-Quellcode:
Liste := TStringList.Create;
try
  // ...
finally
  Liste.Free; // oder: FreeAndNil(Liste);
end;

Geändert von Matze ( 6. Sep 2010 um 18:41 Uhr)
  Mit Zitat antworten Zitat
DevidEspenschied

Registriert seit: 7. Sep 2006
Ort: Berlin
441 Beiträge
 
Delphi 12 Athens
 
#3

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 18:41
Okay, das hatte ich überlesen.

Gibt es keine Möglichkeit, dies ohne Listensortierung durchzuführen?
Devid
Devid Espenschied
Pre-sales Consultant
Embarcadero Germany GmbH
germany.info@embarcadero.com

Kein Support per PN
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 18:42
Nur manuell, indem du vor dem Einfügen selbst in einer Schleife prüft, ob der Eintrag bereits enthalten ist.

Also grob aus dem Kopf:
Delphi-Quellcode:
Included := false;
for i := 0 to Liste.Count - 1 do
begin
  if Liste[i] = 'Eintrag 1then
  begin
    Included := true;
    break;
  end;
end;

if not Included then
  Liste.Add('Eintrag 1');
Natürlich noch schön als Funktion/Methode verpacken und gut ist.

Geändert von Matze ( 6. Sep 2010 um 18:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#5

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 19:10
Mit IndexOf() geht das auch etwas kürzer (macht aber intern wohl genau dasselbe)
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
zeras

Registriert seit: 11. Mär 2007
Ort: Saalkreis
1.643 Beiträge
 
Delphi 12 Athens
 
#6

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 19:53
Mit IndexOf() geht das auch etwas kürzer (macht aber intern wohl genau dasselbe)
.... und der Qulltext wird dafür bestimmt übersichtlicher. Ich nutze IndexOf() für solche Funktionen immer.
Matthias
Es ist nie falsch das Richtige zu tun!
- Mark Twain
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#7

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 19:58
Ich auch, ich wollte damit nur darauf hinweisen, dass man die angeregte Funktion gar nicht selbst schreiben muss, da ja bereits implementiert.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#8

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 20:04
Ich auch, ich wollte damit nur darauf hinweisen, dass man die angeregte Funktion gar nicht selbst schreiben muss, da ja bereits implementiert.
Jaja, ich hab einfach vergessen, dass es diese Funktion gibt. Ist gut jetzt.
Ich würde IndexOf() natürlich auch der manuellen Implementierung vorziehen, keine Frage.
  Mit Zitat antworten Zitat
DevidEspenschied

Registriert seit: 7. Sep 2006
Ort: Berlin
441 Beiträge
 
Delphi 12 Athens
 
#9

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 20:06
Vielen Dank für die Antworten. Ich habe IndexOf implementiert.
Devid
Devid Espenschied
Pre-sales Consultant
Embarcadero Germany GmbH
germany.info@embarcadero.com

Kein Support per PN
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

AW: TStringList ignoriert doppelte Einträge nicht

  Alt 6. Sep 2010, 21:17
Auch wenn der Code, bei einer unsortierten Liste extrem langsam werden kann, was sich Aufgrund des Listentypes nicht ändern lößt.
Eine HashListe oder ein Suchindex in Form eines binären Baums oder einer weiteren Hashliste wäre besser.

Ich würde die OH ändern, vor den langsameren Einfügeoperationen waren und dann den Code so ändern:
Delphi-Quellcode:
procedure TStringList.Put(Index: Integer; const S: string);
begin
  if Cardinal(Index) >= Cardinal(FCount) then
    Error(@SListIndexError, Index);
  if (Duplicates <> dupIgnore) and (FList^[Index].FString <> S) and (IndexOf(S) >= 0) then
    case Duplicates of
      dupIgnore: begin
        Delete(Index);
        Exit;
      end;
      dupError: Error(@SDuplicateString, 0);
    end;
  Changing;
  FList^[Index].FString := S;
  Changed;
end;

function TStringList.AddObject(const S: string; AObject: TObject): Integer;
begin
  if not Sorted then
  begin
    if (Duplicates <> dupIgnore) and (IndexOf(S) >= 0) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;
    Result := FCount;
  end
  else
    if Find(S, Result) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;
  InsertItem(Result, S, AObject);
end;

procedure TStringList.InsertObject(Index: Integer; const S: string; AObject: TObject);
begin
  if Sorted then Error(@SSortedListError, 0);
  if (Index < 0) or (Index > FCount) then Error(@SListIndexError, Index);
  if (Duplicates <> dupIgnore) and (IndexOf(S) >= 0) then
    case Duplicates of
      dupIgnore: Exit;
      dupError: Error(@SDuplicateString, 0);
    end;
  InsertItem(Index, S, AObject);
end;
als neue Komponente ergibt das:
Delphi-Quellcode:
uses
  RTLConsts;

type
  TDupStringList = class(TStringList)
  protected
    procedure Put(Index: Integer; const S: string); override;
  public
    function AddObject(const S: String; AObject: TObject): Integer; override;
    procedure InsertObject(Index: Integer; const S: String; AObject: TObject); override;
  end;

procedure TDupStringList.Put(Index: Integer; const S: string);
begin
  if Cardinal(Index) >= Cardinal(Count) then
    Error(@SListIndexError, Index);
  if (Duplicates <> dupIgnore) and (Strings[Index] <> S) and (IndexOf(S) >= 0) then
    case Duplicates of
      dupIgnore: begin
        Delete(Index);
        Exit;
      end;
      dupError: Error(@SDuplicateString, 0);
    end;
  Inherited;
end;

function TDupStringList.AddObject(const S: string; AObject: TObject): Integer;
begin
  if not Sorted then
  begin
    if (Duplicates <> dupIgnore) and (IndexOf(S) >= 0) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;
    Result := Count;
  end
  else
    if Find(S, Result) then
      case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;
  InsertItem(Result, S, AObject);
end;

procedure TDupStringList.InsertObject(Index: Integer; const S: string; AObject: TObject);
begin
  if Sorted then Error(@SSortedListError, 0);
  if (Index < 0) or (Index > Count) then Error(@SListIndexError, Index);
  if (Duplicates <> dupIgnore) and (IndexOf(S) >= 0) then
    case Duplicates of
      dupIgnore: Exit;
      dupError: Error(@SDuplicateString, 0);
    end;
  InsertItem(Index, S, AObject);
end;
Code ungetestet, da einfach so dahingetippt, aber er sollte funktionieren.
$2B or not $2B

Geändert von himitsu ( 6. Sep 2010 um 21:34 Uhr)
  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 14:27 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