Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Listbox vergleichen (https://www.delphipraxis.net/102608-listbox-vergleichen.html)

Uncle Cracker 31. Okt 2007 22:17


Listbox vergleichen
 
Hey Leute,
ich stehe vor einem "großem" Problem und zwar:

Ich habe zwei Listboxen (bzw. StringListen) und würde diese gern auf den selben Inhalt vergleichen und die selben dann in eine neue ListBox speichern...

Das ist jetzt nicht das Problem, nur sind die Strings in den beiden ListBoxen nicht gleich, sondern nur annähernd.

Beispiel:

Listbox1-Inhalt:

07-1695
07-2488
07-0054
07-1454
...


Listbox2-Inhalt:

07-2545_Test1
07-6894_Test2
07-1695_Test3
07-0654_Test4
...


Jetzt würde ich gern den die Anfangszahlen von Listbox1 mit dem Inhalt von Listbox2 vergleichen und identische in Listbox3 speichern, nur habe ich ein riesiges Performanceproblem, wenn ich das mit zwei For-Schleifen löse, da es über 10000 Einträge in Listbox1 und über 2000 Einträge in Listbox2 sind...

Ich habe mich schon anders dran versucht, nur gelange ich so nicht an ein Ergebnis:

Delphi-Quellcode:
function GetJobID(s: string): string;
begin
  Result := copy(s, 0, 7);
end;

procedure IntersectStrings(sResult, s1, s2: TStrings);
var
  i: Integer;
begin
  sResult.BeginUpdate;
  sResult.Clear;
  for i := 0 to Pred(s1.Count) do
    if s2.IndexOf(GetJobID(s1[i])) >= 0 then
      sResult.Add(s1[i]);
  sResult.EndUpdate;
end;
Jemand sonst einen Vorschlag wie ich das lösen könnte!?


:love: Danke UC

mkinzler 31. Okt 2007 22:48

Re: Listbox vergleichen
 
Oder per Pos()

taaktaak 1. Nov 2007 07:35

Re: Listbox vergleichen
 
Moin, Moin.
Vielleicht wird es schneller, wenn zumindest die größere List temporär sortiert wird und dann die Inhalte der kleineren Liste in der großen (sortierten) Liste gesucht und ggf. übertragen werden. Dann können ja die Werte, sobald ein erstes Vorkommen erkannt wurde alle darauffolgenden Werte (bis wieder ein neuer Wert entdeckt wird) ohne neue Suche übernommen werden. Das sollte eigentlich insgesamt schneller funktionieren.
Wenn in deinem Beispiel s1 für ListBox1 und s2 für Listbox2 steht, scheint mir da auch etwas durcheinander gekommen zu sein - oder??
Gruß
Ralph :spin2:

lbccaleb 1. Nov 2007 08:59

Re: Listbox vergleichen
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich hatte sowas auch schon mal gebraucht schau dir mal nen kleines hilfstool an was ich vor kurzem mal geschrieben hatte, vllt kannst du damit was anfangen wenn ich mich rechtentsinne, habe ich dort sowas auch verarbeitet!!!


(ist nur source)

Luckie 1. Nov 2007 09:06

Re: Listbox vergleichen
 
Zitat:

Zitat von Uncle Cracker
Jemand sonst einen Vorschlag wie ich das lösen könnte!?

Mach das ganze mit Stringlisten und nicht mit Listboxen oder unterdrück zumindest das Neuzeichnen der Listboxen.

marabu 1. Nov 2007 11:39

Re: Listbox vergleichen
 
Hallo,

als ich die Prozedur IntersectStrings() bereit stellte, habe ich auch auf die Bedeutung einer Sortierung hingewiesen. Auch die Aktualisierung der ListBox wird ja unterdrückt. Ein Test zeigt bei mir Zeiten (für Sortierung und Selektion) jeweils deutlich unter 100 Millisekunden.

Delphi-Quellcode:
function RandomStr(size: integer): string;
var
  i: integer;
begin
  SetLength(Result, size);
  for i := 1 to Length(Result) do
    Result[i] := Chr(Ord('A') + Random(26));
end;

procedure IntersectStrings(sResult, s1, s2: TStrings);
var
  i: Integer;
  s: string;
begin
  sResult.BeginUpdate;
  sResult.Clear;
  for i := 0 to Pred(s2.Count) do
  begin
    s := Copy(s2[i], 1, 7);
    if s1.IndexOf(s) >= 0 then
      sResult.Add(s);
  end;
  sResult.EndUpdate;
end;

procedure TDemoForm.ButtonClick(Sender: TObject);
var
  s: TStringList;
  tc: Cardinal;
begin
  s := TStringList.Create;
  tc := GetTickCount;
  s.Assign(ListBox1.Items);
  ShowMessage(Format('assigned: %d', [GetTickCount - tc]));
  tc := GetTickCount;
  s.Sorted := True;
  ShowMessage(Format('sorted: %d', [GetTickCount - tc]));
  IntersectStrings(ListBox3.Items, s, ListBox2.Items);
  ShowMessage(Format('selected: %d', [GetTickCount - tc]));
  s.Free;
end;

procedure TDemoForm.FormCreate(Sender: TObject);
const
  CNT1 = 10000;
  CNT2 = 2000;
var
  i: Integer;
begin
  with ListBox1.Items do
  begin
    BeginUpdate;
    for i := 1 to CNT1 do
      Add(Format('%.2d-%.4d', [Random(100), Random(10000)]));
    EndUpdate;
  end;

  with ListBox2.Items do
  begin
    BeginUpdate;
    for i := 1 to CNT1 do
      Add(Format('%.2d-%.4d_%s', [Random(100), Random(10000), RandomStr(5)]));
    EndUpdate;
  end;
end;
Ich vermute, dass einfach nicht sortiert worden ist. Sortiert wird die große Liste und diese wird auch als zweiter Parameter übergeben. Die kleinere Liste wird als dritter Parameter übergeben und enthält die Einträge mit angehängtem String.

Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 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