Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TComponentList.Sort --> Endlosschleife (https://www.delphipraxis.net/136581-tcomponentlist-sort-endlosschleife.html)

berens 3. Jul 2009 09:48


TComponentList.Sort --> Endlosschleife
 
Hi!

Mein TComponentList.Sort (SortElement) wird niemals fertig. Kann mir jemand sagen, warum?

Delphi-Quellcode:
...
TLayout
private
    FCompareListItems:TListSortCompare;
published
    Objects: TComponentList;
public
...


function InternalSortLayout(Item1, Item2: Pointer): Integer;
begin
  Result := -1;

  if TLayoutElement(Item1).Top < TLayoutElement(Item2).Top then Result := -1;
  if TLayoutElement(Item1).Top > TLayoutElement(Item2).Top then Result := 1;

  if TLayoutElement(Item1).Top = TLayoutElement(Item2).Top then begin
    if length(TLayoutElement(Item1).Text) < Length(TLayoutElement(Item2).Text) then begin
      Result := -1;
    end else begin
      Result := 1;
    end;
  end;
end;

constructor TLayout.Create(_Owner: TComponent = NIL);
begin
  inherited Create(_Owner);
  Objects := TComponentList.Create(True);
  FCompareListItems := InternalSortLayout;
  ...
end;

procedure TLayout.SortElement;
begin
  if Objects.Count > 1 then begin
    Objects.Sort(FCompareListItems);
  end;
end;
Danke im Vorraus.

Hawkeye219 3. Jul 2009 10:01

Re: TComponentList.Sort --> Endlosschleife
 
Hallo berens,

die Vergleichsroutine kann durchaus für zwei identische Einträge aufgerufen werden. Sie muss in diesem Fall den Wert 0 liefern.

Gruß Hawkeye

berens 3. Jul 2009 10:05

Re: TComponentList.Sort --> Endlosschleife
 
Wie besch...eiden ist das denn? oO

Egal wie, so funktioniert es einwandfrei:

Delphi-Quellcode:
function InternalSortLayout(Item1, Item2: Pointer): Integer;
begin
  Result := 0;

  If Item1 = Item2 then begin
    exit;
  end;

  ...

Danke Hawkeye219 :)

p80286 3. Jul 2009 10:07

Re: TComponentList.Sort --> Endlosschleife
 
Hallo berens,

abgesehen von der etwas unglücklichen Benutzing von "If" sehe ich da erst einmal keinen Fehler. Allerdings halte ich folgendes für etwas schneller:
Delphi-Quellcode:
if TLayoutElement(Item1).Top < TLayoutElement(Item2).Top then Result := -1
else
  if TLayoutElement(Item1).Top > TLayoutElement(Item2).Top then Result := 1
  else
  if TLayoutElement(Item1).Top = TLayoutElement(Item2).Top then begin
    if length(TLayoutElement(Item1).Text) < Length(TLayoutElement(Item2).Text) then
      Result := -1 
    else
      Result := 1;
  end;
So läuft er nicht für jeden Satz in drei "If"s.

@Hawkeye219
Wenn er aber unbeding keine "gleichen" Daten haben will? Sowas soll's ja geben.

Gruß
K-H

Oh ich hab nicht aufgepasst:
Delphi-Quellcode:
if length(TLayoutElement(Item1).Text) < Length(TLayoutElement(Item2).Text) then
      Result := -1 
    else
      Result := 1;
Wenn aber der Text gleich ist gibt's ein Problem.
K-H

mirage228 3. Jul 2009 10:07

Re: TComponentList.Sort --> Endlosschleife
 
Das ist eine allgemeine Anforderung an eine Compare Funktion. Du solltest auch eher auf
Delphi-Quellcode:
if (TLayoutElement(Item1).Top = TLayoutElement(Item2).Top) and (length(TLayoutElement(Item1).Text) = Length(TLayoutElement(Item2).Text)
für Gleichheit (= 0) testen.

Viele Grüße

berens 3. Jul 2009 10:12

Re: TComponentList.Sort --> Endlosschleife
 
Das mit gleichen Daten ist nicht das Problem, sondern mit gleichen Items: Warum vergleicht die Liste Apfel1 mit Apfel1? Das Item steht nur einmal in der Liste, und kann deshalb natürlich auch nicht "vor sich" oder "hinter sich" einsortiert werden.


mirage228: Die Sortierung soll primär nach "Top" erfolgen, erst falls diese identlisch ist, nach Textlänge. Sind beide Texte gleichlang, ist es egal.


Ich möchte einfach der Form halber nochmal angemerkt haben, dass die Hilfe in Delphi 2007 seeehr bescheiden ist. Alles zum Thema TList.Sort:
Zitat:

Mit Sort können die Elemente des Arrays Items sortiert werden. Compare ist eine Vergleichsfunktion, die anzeigt, wie die Elemente sortiert sind.
Hier steht nirgendwo beschreiben, wie sortiert wird (Result < > = 0), bzw. dass man auch Vergleiche mit dem selben Item aufpassen muss.

Und zu TListSortCompare:
Zitat:

Das ist der Typ Classes.TListSortCompare.
Wie zur Hölle soll man das alles alleine rausfinden können? Das mit (Result < > = 0) konnte ich nur deswegen "wissen", weil ich hier in DP über einen alten Beitrag zum Thema Sort gestolpert bin, ansonsten hätte ich ausprobieren müssen.

Ich hab zwar Delphi 2009, mag aber noch nicht komplett drauf umsteigen. Wie schaut da die Hilfe aus?

Satty67 3. Jul 2009 10:22

Re: TComponentList.Sort --> Endlosschleife
 
Zitat:

Zitat von berens
Das mit gleichen Daten ist nicht das Problem, sondern mit gleichen Items: Warum vergleicht die Liste Apfel1 mit Apfel1?

Das ist auch bei der eigenen Sortierroutine von Borland so... da werden gleiche Items geswapped. Aber eine CompareFunktion sollte ja immer Größe/Kleiner/Gleich auswerten und entsprechendes Result zurückliefern. Alle Compares in Delphi machen das... größer, kleiner und gleich auswerten und behandeln.

Letztlich aber auch nur konsequent, die komplette Vergleichsprüfung an die Funktion zu übergeben, also auch der Fall Item=Item, weshalb ich das jetzt nicht unbedingt als Design-Fehler sehe.

p80286 3. Jul 2009 10:34

Re: TComponentList.Sort --> Endlosschleife
 
Zitat:

Zitat von berens

mirage228: Die Sortierung soll primär nach "Top" erfolgen, erst falls diese identlisch ist, nach Textlänge. Sind beide Texte gleichlang, ist es egal.


egal im Sinne von "gleich"? dann sollte es auch ein Result=0 geben!

egal im Sinne von "das juckt mich nicht"? Da gibt es bestimmt ein Problem das ordentlich zu programmieren. ;-)

Gruß
K-H

berens 3. Jul 2009 10:40

Re: TComponentList.Sort --> Endlosschleife
 
Delphi-Quellcode:
egal im Sinne von "das juckt mich nicht"? Da gibt es bestimmt ein Problem das ordentlich zu programmieren. ;-)
Naja, "egal" im Sinne von: Je nachdem was der Benutzer sich vorgestellt hat, kann es richtig oder falsch sein.
Das ist hier ein Logikproblem, kein Problem der technischen Umsetzung.
Hier müssen wir auf Feedback der User warten: Was ist passiert, und was hat der Benutzer an dieser Stelle erwartet, bzw. wie kann man festlegen, dass dies oder jenes passieren soll.

Der genannte Fall tritt generell äußerst selten ein, und lässt sich durch ändern von "Top" durch den Benutzer eindeutig klären.

Dafür sich jetzt im vorraus den Kopf zu zerbrechen, lohnt sich nicht (spätestens wenn der erste Kunde kommt und es genau andersherum haben will, als wie wir es dann gelöst haben ;) )


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