Solved

# Sorting record structure

Posted on 2005-05-12
213 Views
Hi,

I am using a simple record structure:

type
KeyAnalyze=Record
Key:string;
Num:integer;
end;

After populating the records, How can I sort in descending order by the "Num" value?
0
Question by:Esopo

LVL 27

Expert Comment

where do you populate the records?
0

LVL 14

Author Comment

var
KeyArray: array of KeyAnalyze;

...
then, within a loop:

SetLength(KeyArray, length(KeyArray) +1);
KeyArray[length(KeyArray) -1].Key:= WhateverString;
KeyArray[length(KeyArray) -1].Num:= WhateverNumber;

*********

Now I need to sort the array of records by the Num value so that I can return the records organized in descending order to the user.

Makes sense?
0

LVL 17

Accepted Solution

here's an example I wrote for you

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
KeyAnalyze = Record
Key:string;
Num:integer;
end;

type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure SortMyArrayByNum;
procedure SortMyArrayByNumDescending;
{ Private declarations }
public
{ Public declarations }
KeyArray: array of KeyAnalyze;
end;

var
Form1: TForm1;

implementation

{\$R *.DFM}

procedure TForm1.SortMyArrayByNum;
var
NoSwap: boolean;
i: integer;
Key_: string;
Num_: integer;
begin
Repeat
NoSwap := true;
For i := 0 to length(KeyArray) - 2 do // -2 because we do +1 later on
begin
if KeyArray[i].Num > KeyArray[i+1].Num then
begin //we have to switch.
NoSwap := False; //We have to tell the sort we aren't done.
Key_ := KeyArray[i].Key; //store
Num_ := KeyArray[i].Num; //store
KeyArray[i].Key := KeyArray[i+1].Key; //put the other in its place.
KeyArray[i].Num := KeyArray[i+1].Num; //put the other in its place.
KeyArray[i+1].Key := Key_; //Put the stored value
KeyArray[i+1].Num := Num_; //Put the stored value
end;
end;
//if there has been even one switch, NoSwap is false;
Until NoSwap
end;

procedure TForm1.SortMyArrayByNumDescending;
var
NoSwap: boolean;
i: integer;
Key_: string;
Num_: integer;
begin
Repeat
NoSwap := true;
For i := 0 to length(KeyArray) - 2 do // -2 because we do +1 later on
begin
if KeyArray[i].Num < KeyArray[i+1].Num then
begin //we have to switch.
NoSwap := False; //We have to tell the sort we aren't done.
Key_ := KeyArray[i].Key; //store
Num_ := KeyArray[i].Num; //store
KeyArray[i].Key := KeyArray[i+1].Key; //put the other in its place.
KeyArray[i].Num := KeyArray[i+1].Num; //put the other in its place.
KeyArray[i+1].Key := Key_; //Put the stored value
KeyArray[i+1].Num := Num_; //Put the stored value
end;
end;
//if there has been even one switch, NoSwap is false;
Until NoSwap
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
//        SortMyArrayByNum;
SortMyArrayByNumDescending;
for i := 0 to length(KeyArray) - 1 do
memo1.lines.add( KeyArray[i].Key + ' ' + IntToStr(KeyArray[i].Num));
end;

begin
SetLength(KeyArray, length(KeyArray) + 1);

KeyArray[length(KeyArray) -1].Key:= Key_;
KeyArray[length(KeyArray) -1].Num:= Num_;
end;

end.
0

LVL 14

Author Comment

Thank you!

I was hoping for a SortStructure() kind of function from Delphi, but your is just as good.
0

LVL 17

Expert Comment

well if you have the enterprise version you might be able to use TBaseArray and override the Sort() method,
otherwise you could use a TObjectList and a class to do the same thing (see below)

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
contnrs; // needed for TObjectList which automatically frees list items

type
TKeyAnalyze = class
public
Key:string;
Num:integer;
Constructor Create(Key_: string; Num_: integer);
end;

type
TForm2 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
MyList: TObjectList;
end;

var
Form2: TForm2;
function SortByNum(Item1, Item2: Pointer): Integer;
function SortByNumDescending(Item1, Item2: Pointer): Integer;

IMPLEMENTATION

{\$R *.DFM}

{ sort routines }

function SortByNum(Item1, Item2: Pointer): Integer;
begin
if TKeyAnalyze(Item1).Num < TKeyAnalyze(Item2).Num then
result := -1
else
if TKeyAnalyze(Item1).Num > TKeyAnalyze(Item2).Num then
result := 1
else
result := 0;
end;

function SortByNumDescending(Item1, Item2: Pointer): Integer;
begin
if TKeyAnalyze(Item1).Num > TKeyAnalyze(Item2).Num then
result := -1
else
if TKeyAnalyze(Item1).Num < TKeyAnalyze(Item2).Num then
result := 1
else
result := 0;
end;

{ KeyAnalyze }

constructor TKeyAnalyze.Create(Key_: string; Num_: integer);
begin
inherited Create;
Key := Key_;
Num := Num_;
end;

{ Form }

procedure TForm2.FormCreate(Sender: TObject);
var
i: integer;
begin
MyList := TObjectList.Create;
MyList.Sort(SortByNumDescending);
for i := 0 to MyList.Count - 1 do
memo1.lines.add( TKeyAnalyze(MyList[i]).Key + ' ' + IntToStr( TKeyAnalyze(MyList[i]).Num) );
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
MyList.Free;
end;

end.
0

LVL 14

Author Comment

Very interesting. Is this kind of power that makes me proud of using Delphi :D
0

## Featured Post

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Need more eyes on your posted question? Go ahead and follow the quick steps in this video to learn how to Request Attention to your question. *Log into your Experts Exchange account *Find the question you want to Request Attention for *Go to the e…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…