Solved

Sorting Array of records with multiple sort keys

Posted on 2004-03-31
5
717 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
  • 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
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…

808 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