Board index » delphi » TList Sorting Question

TList Sorting Question

I was hoping someone could help me out with a question about sorting a
TList.  I have a TList with about 100 pointers to records of this type:

record MyRecord
  name: array of char[50];
  person: array of char[50];
  number: Integer;
end;

I would like to be able to alpha-sort this list of records on the fly using
the first 10 characters of the "name" variable (the first one in each
record).

Is this possible or do I have to write some huge routine to do it for me?

thanks in advance ;)

Shane Bridges
Please cc to kinet...@adelphia.net

 

Re:TList Sorting Question


Quote
Shane wrote:

> I was hoping someone could help me out with a question about sorting a
> TList.  I have a TList with about 100 pointers to records of this type:

> record MyRecord
>   name: array of char[50];
>   person: array of char[50];
>   number: Integer;
> end;

> I would like to be able to alpha-sort this list of records on the fly using
> the first 10 characters of the "name" variable (the first one in each
> record).

> Is this possible or do I have to write some huge routine to do it for me?

Commercial toolkits such as SysTools (TurboPower Software) provide this
capability, but so do lots of other public-domain and freeware
components.

These routines rely upon you to supply a "Compare" function that, given
two records, returns a value greater than, equal to, or less than zero
as an indication of how to sort the values.  They customarily use the
same Quicksort algorithm that Delphi uses to sort lists.

Armed with this information you could "do it yourself" but you can
download or buy someone else's work faster.

Re:TList Sorting Question


In article <1Lae3.5284$ll5.43...@server1.news.adelphia.net>, "Shane"

Quote
<kinet...@adelphia.net> writes:
>I was hoping someone could help me out with a question about sorting a
>TList.  I have a TList with about 100 pointers to records of this type:

>record MyRecord
>  name: array of char[50];
>  person: array of char[50];
>  number: Integer;
>end;

>I would like to be able to alpha-sort this list of records on the fly using
>the first 10 characters of the "name" variable (the first one in each
>record).

Code a compare function which accepts two pointers (to the TList items) and
returns -1, 0, or +1. One usually uses (case sensitive) AnsiCompareStr or (case
insensitive) ANSICompareText to do the comparison but you can code it yourself
if you want a "funny" sort. Then call the TList Sort method with a pointer to
this function as its parameter. Delphi carries out the actual sorting (using a
quick-sort routine) using your comparison function.

function MyListCompareProc(P1, P2 : Pointer) : integer;
var
  R1Str, R2Str : string[10];
begin
  R1Str := Copy(TMyRecord(P1^).Name, 1, 10);
  R2Str := Copy(TMyRecord(P2^).Name, 1, 10);
  Result := AnsiCompareText(R1Str, R2Str);
end;

Note that this must be a general function & not a method (ie no class qualifier
as a prefix to the function name). You must put the function in your code
before the call to the TList.Sort, or put a its header immediately after the
implementation clause in your unit.

Then to sort :-

  MyList.Sort(MyListCompareProc);

You can of course code a number of different sort functions and call the
appropriate one for the particular sort you want in the MyList.Sort method
call.

Alan Lloyd
alangll...@aol.com

Re:TList Sorting Question


<<Shane:
I was hoping someone could help me out with a question about sorting a
TList.  I have a TList with about 100 pointers to records of this type:

record MyRecord
  name: array of char[50];
  person: array of char[50];
  number: Integer;
end;

I would like to be able to alpha-sort this list of records on the fly using
the first 10 characters of the "name" variable (the first one in each
record).

Is this possible or do I have to write some huge routine to do it for me?

Quote

It's easy:

// I modified your record to a pascal-type declaration:

MyRecord = record
  name: array [0..50] of char;
  person: array [0..50] of char;
  number: Integer;
end;

var
  NameList: TList;

function CompareMyRecords(Item1, Item2: Pointer): Integer;
begin
  result:=ANSICompareText(Copy(MyRecord(Item1^).name, 1, 10), Copy(MyRecord(Item2^).name, 1, 10));
end;

procedure TForm1.SortList;
begin
  NameList.Sort(CompareMyRecords);
end;

Goiod luck !

--

Bjoerge

Re:TList Sorting Question


An option is to use a tStringList with its Sorted property set True instead
of a tList. Put the Key in the string and a pointer to the record instance
in the Object, eg aStringList.AddObject (keyValue, tObject (pMyRecord)).

Quote
Shane <kinet...@adelphia.net> wrote in message

news:1Lae3.5284$ll5.43895@server1.news.adelphia.net...
Quote
> I was hoping someone could help me out with a question about sorting a
> TList.  I have a TList with about 100 pointers to records of this type:

> record MyRecord
>   name: array of char[50];
>   person: array of char[50];
>   number: Integer;
> end;

> I would like to be able to alpha-sort this list of records on the fly
using
> the first 10 characters of the "name" variable (the first one in each
> record).

> Is this possible or do I have to write some huge routine to do it for me?

> thanks in advance ;)

> Shane Bridges
> Please cc to kinet...@adelphia.net

Re:TList Sorting Question


Quote
> record MyRecord
>   name: array of char[50];
>   person: array of char[50];
>   number: Integer;
> end;

OOPS, I actually crossed Pascal with the C declaration char[50] :)

Thanks for all the replies...this will help a lot.

Shane

Quote

> // I modified your record to a pascal-type declaration:

> MyRecord = record
>   name: array [0..50] of char;
>   person: array [0..50] of char;
>   number: Integer;
> end;

Re:TList Sorting Question


Quote
Bj?rge S?ther wrote:

>   result:=ANSICompareText(Copy(MyRecord(Item1^).name, 1, 10),

Minor point, but since this *almost* indicates that youre typecasting
things of different sizes, it's slightly more natural to say:

type
  PMyRecord=^MyRecord;

result:=ANSICompareText(Copy(PMyRecord(Item1)^.name, 1, 10),

and this is a closer approximation to what the compiler does anyway.

MH.

--
Martin Harvey.
mar...@aziraphale.demon.co.uk
mc...@harvey27.demon.co.uk
http://www.harvey27.demon.co.uk/mch24/
EFFNet: Diaspar-
ICQ: 37298917

Jesus replied: "I am the way, the truth, and the life;
no one comes to the Father, except by me."
(John 14:6).

Re:TList Sorting Question


In article
<19990630033255.17959.00002...@ngol01.aol.com>,
  alangll...@aol.com (AlanGLLoyd) wrote:
Quote
> In article

<1Lae3.5284$ll5.43...@server1.news.adelphia.net>,
"Shane"
Quote
> <kinet...@adelphia.net> writes:

> >I was hoping someone could help me out with a

question about sorting a
Quote
> >TList.  I have a TList with about 100 pointers

to records of this type:
Quote

> >record MyRecord
> >  name: array of char[50];
> >  person: array of char[50];
> >  number: Integer;
> >end;

> >I would like to be able to alpha-sort this list

of records on the fly using
Quote
> >the first 10 characters of the "name" variable

(the first one in each
Quote
> >record).

> Code a compare function which accepts two

pointers (to the TList items) and
Quote
> returns -1, 0, or +1. One usually uses (case

sensitive) AnsiCompareStr or (case
Quote
> insensitive) ANSICompareText to do the

comparison but you can code it yourself
Quote
> if you want a "funny" sort. Then call the TList

Sort method with a pointer to
Quote
> this function as its parameter. Delphi carries

out the actual sorting (using a
Quote
> quick-sort routine) using your comparison
function.

> function MyListCompareProc(P1, P2 : Pointer) :
integer;
> var
>   R1Str, R2Str : string[10];
> begin
>   R1Str := Copy(TMyRecord(P1^).Name, 1, 10);
>   R2Str := Copy(TMyRecord(P2^).Name, 1, 10);
>   Result := AnsiCompareText(R1Str, R2Str);
> end;

> Note that this must be a general function & not

a method (ie no class qualifier
Quote
> as a prefix to the function name). You must put

the function in your code
Quote
> before the call to the TList.Sort, or put a its

header immediately after the
Quote
> implementation clause in your unit.

> Then to sort :-

>   MyList.Sort(MyListCompareProc);

> You can of course code a number of different

sort functions and call the
Quote
> appropriate one for the particular sort you want

in the MyList.Sort method

Quote
> call.

> Alan Lloyd
> alangll...@aol.com

If your char arrays contain null terminated
strings, and would like to sort by name, person
and then number, why using tempory strings?

type
  PMyRecord : ^MyRecord;

function MyListCompareProc(P1, P2 : Pointer) :
integer;
var
   p, q : PMyRecord;
begin
   Result := StrComp( PChar( p^.Name),
PChar(q^.Name));
   if Result = 0 then
   begin
      Result := StrComp( PChar( p^.person), PChar(
q^.person) );
      if Result = 0 then
         Result := p^.number - q^.number;

   end;
end;

use AnsiStrComp instead of StrComp is you want
case insensitive comparision.

Henk W. Klijn Hesselink
klijn$NO_SPAMgmx.net

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Re:TList Sorting Question


Quote
In article <7m4lv2$7n...@nnrp1.deja.com>, kli...@my-deja.com writes:
>If your char arrays contain null terminated
>strings, and would like to sort by name, person
>and then number, why using tempory strings?

Because the original poster asked to sort on the first 10 characters of the
strings.

I find that it often helps to accept the customers requirements <gg>

Alan Lloyd
alangllo...@aol.com

Other Threads