Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Array of record nach verschiedenen Elementen sortieren


Ruditschka - So 08.02.04 17:01
Titel: Array of record nach verschiedenen Elementen sortieren
Hallo!

Ich habe folgendes Array

Delphi-Quelltext
1:
BankSet: array of TBankData                    

mit folgender Typdeklaration

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
type
  TBankData = record
    Number: Byte;
    Name: string;
    Position: Byte;
  end;


Innerhalb des Programms soll das Array nun mehrmals umsortiert werden. Einmal nach BankNumber, ein anderes mal nach BankPosition oder Number. Bis jetzt habe ich dafür jedes mal eine eigene Sort-Prozedur geschrieben (bzw. nur abgeändert ;)).

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure BankPositionSort(var a: array of TBankData; Lo, Hi: integer);
  procedure QuickSort(l, r: integer);
  var
    i, j: integer;
    x: Byte;
    y: TBankData;
  begin
    i := l; j := r; x := a[(l+r) DIV 2].Position;
    repeat
      while a[i].Position < x do inc(i);
      while x < a[j].Position do dec(j);
      if i <= j then
      begin
        y := a[i]; a[i] := a[j]; a[j] := y;
        i := i + 1; j:=j-1;
      end;
    until i>j;
    if l < j then QuickSort(l, j);
    if i < r then QuickSort(i, r);
  end{ QuickSort }
begin
  QuickSort(Lo,Hi);
end;


Gibt es eine Möglichkeit, der Prozedur einen Parameter mitzugeben, der das entsprechende Record-Element aufnimmt? Etwa so:

Delphi-Quelltext
1:
2:
3:
procedure BankPositionSort(var a: array of TBankData; Lo, Hi: integer; Element: string{?});
{...}
x := a[(l+r) DIV 2].Element^;  // Sieht aus wie ein Pointer, aber ich denke, dass damit deutlich wird, dass der String quasi dereferenziert werden soll.


Danke an Alle, die sich jetzt den Kopf zerbrechen.

Gruß
Christoph

P.S.: Bei dem kleinen record geht das mit den einzelnen Sort-Prozeduren noch, aber unter anderem habe ich auch ein Array of Record mit 9 Elementen. Da wird's dann schnell unübersichtlich.


Michael Stenzel - Mo 09.02.04 03:08

Hallo Ruditschka.

Den Namen als String übergeben kann man nicht, aber du kannst Dir eine Funktion schreiben, mit der man die Daten vergleicht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
type BankDataVerg = (Number,_Position,_Name); // nur Position gibt einen Namenskonflikt dito mit Name! 
...
procedure BankPositionSort(var a: array of TBankData; Lo, Hi: integer; Vergleich : BankDataVerg);
  function IsGroesser(var Erster, Zweiter : integer):boolean;
  begin
      case Vergleich of
        Number   :  Result := a[Erster].Number > A[Zweiter].Number;
        _Position : Result := a[Erster].Position > A[Zweiter].Position;
       _Name      : Result := a[Erster].Name > A[Zweiter].Name;
      end;
  end;

  procedure QuickSort(l, r: integer);
  var
    i, j, x : integer;
    y: TBankData;
  begin
    i := l; j := r; x := (l+r) DIV 2;
    repeat
      while IsGroesser(x,i) do inc(i);
      while IsGroesser(j,x) do dec(j);
      if i <= j then
      begin
        y := a[i]; a[i] := a[j]; a[j] := y;
        i := i + 1; j:=j-1;
      end;
    until i>j;
    if l < j then QuickSort(l, j);
    if i < r then QuickSort(i, r);
  end{ QuickSort }
begin
  QuickSort(Lo,Hi);
end;

....

BankPositionSort(BankSet,0,255, _Position);   // Aufruf


mfg
Michael.


Ruditschka - Mo 09.02.04 18:03

Hallo Michael!

Zuerst mal Danke für die Hilfe. Dazu habe ich allerdings noch eine Verständnisfrage:

Zitat:

Delphi-Quelltext
1:
type BankDataVerg = (Number,_Position,_Name); // nur Position gibt einen Namenskonflikt dito mit Name!                    


Warum kann gibt es den Namenskonflikt nur bei Position und Name aber nicht bei Number?
Und warum soll es überhaupt einen Namenskonflikt geben? Vergleich (bzw. BankDataVerg) ist doch ein anderer Typ (als TBankData)?!

Werd's aber trotzdem gleich mal ausprobieren.

Gruß
Christoph


Michael Stenzel - Di 10.02.04 01:37

Hallo Christoph.

Weil es in Delphi viele Komponenten sind, die den Namen "Position" und den Namen "Name" als eigenschaft deklarieren. Wenn nun im Gültigkeitsbereich von z. B. TForm1 die Prozedur "BankPositionSort" aufgerufen wird kann Delphi den Parameter nicht eindeutig bestimmen.
Anstatt den Typ "BankDataVerg" zu verwenden setzt Delphi hier TForm1.Name ein, was zu einer Fehlermeldung führt. Desshalb den Unterstrich vor dem Bezeichner, um nicht irgentwelche Kürzel als Bezeichner wählen zu müßen und keine Fehler im Source zu haben.

mfg
Michael.


Ruditschka - Di 10.02.04 17:29

Klingt einleuchtend.

Danke für die Hilfe.

Gruß
Christoph


Anonymous - Di 10.02.04 17:43

Aus diesem Grund werden auch i.d.R. prefixe angehängt:

z.B.

Delphi-Quelltext
1:
2:
type
 TBankDataVerg = (bdvNumber, bdvPosition, bdvName)