Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi TList.sort(@nirvana) warum will TList.sort() nicht wie ich? (https://www.delphipraxis.net/57881-tlist-sort-%40nirvana-warum-will-tlist-sort-nicht-wie-ich.html)

Corelgott 28. Nov 2005 11:29


TList.sort(@nirvana) warum will TList.sort() nicht wie ich?
 
hi @ all,

ich habe eine Liste (TObjectList);

bei dieser liste rufe ich irgendwann Liste.sort (<- ist standard von TList; brauch nur ne funk und dann passt das) auf;
Nur mal so nebenbei: TCmd ist ein Obj abegleitet von TObject; Rechtprimitiv... wollte bloß keine record nehmen ^^

Code:
function elementSort(Item1, Item2: Pointer): Integer;
var
  res : Integer;
  obj1, obj2  : TCmd;

begin
  res := 1;

  obj2  := TCmd(item2^);
  obj1  := TCmd(Item1^);

  if ((obj1.priority < obj2.priority) and
      (obj1.processed = cmsPending)) then
    res := -1;

  result := res;
end;

procedure TForm1.OnWasWeissIch(foobar : TObject);
begin
  list.sort(@elementSort);
end;
So 1. darf elementSort keine funktion der klasse TForm1 sein... :gruebel: (Sonst passt das nicht; hmm villeicht, weil methoden von objekten in delphi nicht statisch seien können? Bzw. könne Sie das überhaupt und wenn ja wie? aber das mal nur so nebenbei... **das ist mal wieder ne super frage für Luckie ^^)

2. Bekomme ich beim casten von item1 auf obj1 immer eine AccessViolation... :shock: warum das?; Die daten in der Liste an sich sehen gut aus... (Keine seltsamen unsinnigen Pointer oder so)

Wenn ich das fieh debuggen will, und in die obj1, obj2 rein schauen will, kann es das nicht, weil die funktion ja gar nicht zum objekt gehört, sondern eine statische "Unit"-Prozedure ist (**unwissenheit + dünnes eis... gibt es so was überhaupt?)

So weit so gut.. Ich dachte mir da bemühe ich mal die Hilfe und schau wie die das machen:

So und nun wird es kriminell:

Code:
function CompareNames(Item1, Item2: Pointer): Integer;
begin
  Result := CompareText((Item1 as TComponent).Name, (Item2 as TComponent).Name);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  List1.Sort(@CompareText);
end;
von meinem verständnis her, wird hier die methode CompareNames, die man extra geschreiben hat, gar nicht benutzt?! :shock:
Weil der pointer der "Methode" die das Sortier-Kreterium ausrechnet ist ja hier CompareText und nicht CompareNames...
Passt durch Zufall auch... aber?! :roll:

Oder bin ich hier auf einem völlig falschen Dampfer?"

Hat da mal wer ne idee oder einen Anstroß für mich!?

thx & cya
Corelgott

teebee 28. Nov 2005 12:00

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Zu 1: Sort erwartet als Parameter halt eine 'einfache' Funktion und keine Methode.
Zu 2: Lass mal den Dreferenzierungsoperator weg oder caste mit as.
Zu 3: Das Beispiel aus der OH ist tatsächlich falsch.

Gruß, teebee

Corelgott 28. Nov 2005 13:57

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
hmm thx
für die Antwort...


Zitat:

Zitat von teebee
Zu 1: Sort erwartet als Parameter halt eine 'einfache' Funktion und keine Methode.

ok... **das @ streich...

Zitat:

Zitat von teebee
Zu 2: Lass mal den Dreferenzierungsoperator weg oder caste mit as.

:shock: ok... habe ich gemacht & funzt... aber ist schon ertwas seltsam einen pointer nicht zu dereferenzieren und ihn einfach "zu" einen Object zu casten... :pale:

aber solage es geht :-D

Zitat:

Zitat von teebee
Zu 3: Das Beispiel aus der OH ist tatsächlich falsch.

:P *ohne worte*

hmm somit ist das ganze so wie es soll fertig...
Habe zwar noch ein paar kleinere probs mit der reihnfolge (@gleichwertige einträge nicht vertauschen..) aber sonst... nice!

thx & cya
Corelgott

teebee 28. Nov 2005 14:46

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Zitat:

Zitat von Corelgott
:shock: ok... habe ich gemacht & funzt... aber ist schon ertwas seltsam einen pointer nicht zu dereferenzieren und ihn einfach "zu" einen Object zu casten... :pale:

Eine Objektreferenz ist auch nur ein typisierter Zeiger, mit dem Unterschied zu gewöhnlichen Zeigern, dass man ihn nicht explizit zu dereferenzieren braucht (darf man sogar nicht), das macht der Compiler für einen.

In diesem Kontext wird aber gar nicht dereferenziert, Du sagst dem Compiler nur "tu mal so, als hättest Du statt eines einfachen Pointers einen Zeiger auf ein Objekt bekommen", eben weil nicht das Objekt selbst übergeben wurde, sondern eine Referenz darauf.

Gruß, teebee

Khabarakh 28. Nov 2005 15:37

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Zitat:

Zitat von Corelgott
Sonst passt das nicht; hmm villeicht, weil methoden von objekten in delphi nicht statisch seien können?

Doch, können sie.
Delphi-Quellcode:
class procedure Foo;
Der Unterschied liegt aber darin, dass Methoden immer einen versteckten Self-Parameter besitzen. Deshalb gibt es getrennt Methoden- (mit .. of object) und "normale" Prozedurenzeigertypen.

ArmyMan 25. Apr 2006 11:02

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Wie kann ich nach 2 Spalten sortieren?
z.B. zuerst nach Spalte "a" dann nach Spalte "b" sortieren
Code:
Ausgangstabelle:  Diese Tabelle will ich:
+-------+          +-------+
| a | b |          | a | b |
+-------+          +-------+
| 4 | 4 |          | 1 | 6 |
| 3 | 9 |          | 2 | 6 |
| 2 | 6 |          | 3 | 2 |
| 3 | 2 |          | 3 | 9 |
| 4 | 7 |          | 4 | 4 |
| 1 | 6 |          | 4 | 7 |
+-------+          +-------+
Versteht ihr was ich meine?? :gruebel:

Greetz

ArmyMan 25. Apr 2006 15:13

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Ich habe mal eine nicht 100%ige Lösung. In diesem Beispiel kann die Zahl in der Spalte b höchstens 999 sein. Falls man aber weiss wie gross die Zahl höchstens sein wird, kann man bei dem "*1000" einen grösseren / kleineren faktor nehmen.

Delphi-Quellcode:
type
  TItem = Record
            a : Integer;
            b : Integer;
          end;
  pItem = ^TItem;

...

var
  List : TList;

function CompareValues(Item1 : Pointer; Item2 : Pointer) : Integer;
var
  pItem1, pItem2 : pItem;
  z1, z2 : integer;
begin
  pItem1 := pItem(Item1);
  pItem2 := pItem(Item2);
  z1 := (pItem1^.a*1000)+pItem1^.b;
  z2 := (pItem2^.a*1000)+pItem2^.b;

  if z1 > z2
  then Result := 1
  else if z1 = z2
  then Result := 0
  else Result := -1;
end;

List.Sort(CompareValues);
Greetz

Khabarakh 25. Apr 2006 15:17

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Du bist kreativ, das muss man dir lassen ;) .
Delphi-Quellcode:
Result := Sign(Item1.a - Item2.a);
if Result = 0 then
  Result := Sign(Item1.b - Item2.b);

ArmyMan 25. Apr 2006 15:24

Re: TList.sort(@nirvana) warum will TList.sort() nicht wie i
 
Und warum kam das nicht früher? :wall:

Thx & Greetz


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz