Solved

Sorting Array of records with multiple sort keys

Posted on 2004-03-31
5
724 Views
Last Modified: 2010-04-05
I need a function that will sort an array of records, using multiple keys, i.e. similar to using
ORDER BY customer_no, Inv_date, ord_number in SQL.

The number of records in the array will not be very large, probably only several hundred maximum.

Any guidance will be greatly appreciated.

Alan
0
Comment
Question by:alanjbrown
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10730090
you may use a tlist or tstringlist as your record-container,
rather than an array, then u can use the customsort capability
of this objects.

just ask if you need advice about this.

meikl ;-)
0
 
LVL 1

Author Comment

by:alanjbrown
ID: 10730992
Meikl

I think that I need some additional help. In  Delphi help I can't find any reference to  customsort. Is this available in Delphi 4?
An example using  multiple keys would be useful.

Alan
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 250 total points
ID: 10731444
well, a sample

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    fList : TList;
    procedure DisplayList;
  public
    { Public declarations }
  end;

  PToOrderRec = ^TToOrderRec;
  TToOrderRec = record
                  customerName : String[100];
                  Customer_no  : Integer;
                  Inv_Date : TDateTime;
                  OrderNo  : Integer;
                end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

function RandomStr(ALen : Integer) : String;
var i : integer;
begin
  result := '';
  for i := 1 to ALen do
    result := result + chr(random(26)+65);
end;

function RandomInt(Range : Integer) : Integer;
begin
  result := Random(Range);
end;


//sort Customer_no, Inv_Date, OrderNo
function CustomSort(p1,p2 : pointer) : Integer;
var pa, pb : PToOrderRec;  //just to read it better
begin
  pa := PToOrderRec(p1);
  pb := PToOrderRec(p2);
  result := 0;
  if      pa^.Customer_no > pb^.Customer_no then
    result := 1
  else if pa^.Customer_no < pb^.Customer_no then
    result := -1
  else if pa^.Inv_Date > pb^.Inv_Date then
    result := 1
  else if pa^.Inv_Date < pb^.Inv_Date then
    result := -1
  else if pa^.OrderNo > pb^.OrderNo then
    result := 1
  else if pa^.OrderNo < pb^.OrderNo then
    result := -1
  else
    result := 0;
end;

procedure TForm1.DisplayList;
var
  i : integer;
  s : string;
begin
  for i := 0 to flist.Count-1 do
  begin
    s :=     PToOrderRec(fList[i])^.customerName + ' - ';
    s := s + IntToStr(PToOrderRec(fList[i])^.Customer_no) + ' - ';
    s := s + DateToStr(PToOrderRec(fList[i])^.Inv_Date) + ' - ';
    s := s + IntToStr(PToOrderRec(fList[i])^.Orderno);
    memo1.Lines.Add(s);
  end;
  memo1.Lines.Add('<---------------------------------------------->');
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  i : integer;
  p : PToOrderRec;
begin
  //simulate record
  for i := 1 to 100 do
  begin
    new(p);
    p^.customerName := RandomStr(25);
    p^.Customer_no := RandomInt(999999);
    p^.Inv_Date := RandomInt(trunc(now));
    p^.OrderNo := RandomInt(999999);
    fList.Add(p);
  end;
  //Output unsorted
  DisplayList;
  //sort
  flist.Sort(CustomSort);
  //Output sorted
  DisplayList;
  //free memory
  for i := 0 to flist.Count-1 do
    dispose(PToOrderRec(flist[i]));
  flist.Clear;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  flist := TList.Create;
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
  flist.Free;
end;

end.

just ask if somewhat unclear

meikl ;-)
0
 
LVL 1

Author Comment

by:alanjbrown
ID: 10731500
It will not compile. Get error Variants.dcu not found

Alan
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10731527
hum, sorry,
just remove the variants part from the uses clause
(was introduced with delphi6)

meikl ;-)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

737 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question