Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Liste von Records sortieren (https://www.delphipraxis.net/214622-liste-von-records-sortieren.html)

Maekkelrajter 8. Feb 2024 15:58

Liste von Records sortieren
 
Gegeben sei eine Liste von Records:
Delphi-Quellcode:
Type

                     TMyRecord = Record
                         order : Integer;
                      position : Integer;
                           key : ansistring;
                                 end;

                 TMyRecordList = TList<TMyRecord>;


function ComparePosition(Item1, Item2: Pointer): Integer;
begin
  ????
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  MyRecordList.Sort(@ComparePosition);
end;
Diese Liste hat maximal 8 Einträge und soll nach 'position' sortiert werden. Das sollte eigentlich kein Problem sein. Aber ich kriege den Aufruf von TList.Sort bzw. ComparePosition um's Verrecken nicht hin! Oder geht das irgendwie ganz anders?
Ich brauche dringend einen Denkanstoß!

Gruß LP

himitsu 8. Feb 2024 16:03

AW: Liste von Records sortieren
 
Jupp, sort sorttiert "binär",
aber willst du nach "logischem" Inhalt eines/mehrerer Felder des Records sortieren, dann brauchst du einen Comparer, welcher als Parameter an Sort übergeben wird.

Zitat:

In diesem Fall sind mußt du auch noch casten.
Delphi-Quellcode:
PMyRecord(Item1)^
oder
Delphi-Quellcode:
TMyRecord(Item1^)

[edit]
Wollte grade sagen, dass du besser die generische TList<> verwenden solltest,
aber tutst du ja schon.
Dann schau dir mal an, wie der Sort-Parameter definiert ist.

* ein Interface (IComparer)
* also nun eine Funktion suchen, welche ein IComarer zurückgibt und am Besten eine "Funktion" rein nimmt
* oder selber eine Klasse schreiben, welche IComarer implementiert
* oder eben nach einer fertigen Klasse für das Interface suchen, welche es implementiert (TComparer)
* dafür mußt du dir also eine Instanz erstellen (irgendwas mit "Construct") ... schau einfach mal in die Generics-Units.

[add]
Auf die Schnelle mal etwas für ein TArray<> gefunden, aber ist prinzipiell gleich.
Delphi-Quellcode:
  TArray.Sort<TComponent>(FFormDataSources, TComparer<TComponent>.Construct(function(const Left, Right: TComponent): Integer
    begin
      Result := CompareStr(Left.Name, Right.Name); //Nach Komponentname sortieren
    end));

shebang 8. Feb 2024 16:59

AW: Liste von Records sortieren
 
Zitat:

Zitat von Maekkelrajter (Beitrag 1533218)
Ich brauche dringend einen Denkanstoß!

Delphi-Quellcode:
MyRecordArray : TArray<TMyRecord>;

TArray.Sort<TMyRecord>(MyRecordArray, TComparer<TMyRecord>.Construct(
function(const Left, Right : TMyRecord) : Integer begin
  Result := TComparer<Integer>.Default.Compare(Left.position, Right.position);
end));

himitsu 8. Feb 2024 17:03

AW: Liste von Records sortieren
 
Eigentlich für TList, aber OK.

PS: Delphi-Referenz durchsuchenCompareValue aus der System.Math

Redeemer 8. Feb 2024 20:14

AW: Liste von Records sortieren
 
Wenn der benötigte Platz im AnsiString nicht so groß ist, dann würde sogar schlicht das Ändern auf ShortString reichen.

Uwe Raabe 8. Feb 2024 20:55

AW: Liste von Records sortieren
 
Zitat:

Zitat von Redeemer (Beitrag 1533242)
Wenn der benötigte Platz im AnsiString nicht so groß ist, dann würde sogar schlicht das Ändern auf ShortString reichen.

Nicht wirklich. Bei einem Byte-Vergleich des Records würde erst nach order, dann nach position, dann nach der Länge des ShortStrings und dann nach seinem Inhalt verglichen. Gewünscht ist aber:
Zitat:

Zitat von Maekkelrajter (Beitrag 1533218)
soll nach 'position' sortiert werden.


Redeemer 8. Feb 2024 21:00

AW: Liste von Records sortieren
 
Ach stimmt, und dann auch noch das Längenbyte! Danke für die Klärung.

himitsu 8. Feb 2024 21:16

AW: Liste von Records sortieren
 
Ein statisches #0-terminiertes Char-Array. (der Rest muß auch mit #0 gefüllt sein, wenn nachfolgend noch weitere Felder kommen)

Aber so schwer ist das mit dem Comparer nicht unbedingt.

Maekkelrajter 9. Feb 2024 11:05

AW: Liste von Records sortieren
 
Zitat:

Zitat von himitsu (Beitrag 1533245)
Aber so schwer ist das mit dem Comparer nicht unbedingt.

Für mich schon. :(
Nach langem Suchen und vielen Versuchen funktioniert's nun so:
Delphi-Quellcode:
   
    MyRecordList.Sort(IComparer<TMyRecord>(
    function(const L, R: TMyRecord): Integer
    begin
      Result := CompareValue(L.position, R.position);
    end));
Danke an alle für die 'Denkanstöße'.

Gruß LP


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