BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Index Records

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Pete Watts
Guest





PostPosted: Tue Feb 10, 2004 4:02 pm    Post subject: Index Records Reply with quote



Hi

I use a record structure to hold data from a table,it looks like this:

type
TRecInfo = record
SiteName: string[30];
AppName: string[25];
SiteNum: string[6];
end;

var
Grec: array of TRecInfo;


I get data back from the record like this:

for i := Low(Grec) to High(Grec) do
begin
ShowMessage('Grec is: '+Grec[i].SiteName+' '+Grec[i].AppName+'
'+
Grec[i].SiteNum);
end;

Can anyone tell me how I may sort or index the record structure so
that the field "Sitename" is in order when I access the data.

Thanks

PW

Back to top
Malte Persike
Guest





PostPosted: Tue Feb 10, 2004 4:45 pm    Post subject: Re: Index Records Reply with quote



On Tue, 10 Feb 2004 16:02:03 +0000, Pete Watts <pwa334 (AT) aol (DOT) com> wrote:

....snip
Quote:
Can anyone tell me how I may sort or index the record structure so
that the field "Sitename" is in order when I access the data.


Hi Pete,

you have to do it with a sort routine that does not compare the
entries of the Grec array but takes the .SiteName property as a
sorting key.
I once implemented a quicksort algorithm for a TList and copy/pasted
the modified code below. Compiling and working are not guaranteed but
I think you'll get the picture. Note that the quicksort is a recursive
type. There are non-recursive implementations which are easier to
understand and debug.

Kind regards,
Malte

--

// Quicksort: Sorts array A from item index L to R
// Result: Returns true if any sorting was necessary

function QuickSort(var A: TGrecArrayType; L, R: Integer): Boolean;
var
I, J: Integer;
P: string;
T: TRecInfo;
retval: Boolean;
begin
retval:= false;
repeat
I:= L;
J:= R;
P:= A[(L + R) shr 1].SiteName;
repeat
while (StrComp(PChar(A[I].SiteName), PChar(P))<0) do begin
inc(I);
end;
while (StrComp(PChar(A[I].SiteName), PChar(P))>0) do begin
dec(J);
end;

if (I <= J) then begin
T:= A[I];
A[I]:= A[J];
A[J]:= T;
inc(I);
dec(J);

retval:= true;
end;
until (I > J);
if (L < J) then begin
retval:= retval or QuickSort(A, L, J);
end;

L := I;
until (I >= R);

Result:= retval;
end;


---

The above e-mail address is not valid. To
contact me, please use my real e-mail address:

malte AT t DASH online DOT de

Back to top
Harley Pebley
Guest





PostPosted: Tue Feb 10, 2004 11:24 pm    Post subject: Re: Index Records Reply with quote



Quote:
I use a record structure to hold data from a table,it looks like this:

type
TRecInfo = record
...
end;

var
Grec: array of TRecInfo;

Can anyone tell me how I may sort or index the record structure so
that the field "Sitename" is in order when I access the data.

Instead of storing the records in an array, use a TList, then sorting is a
matter of Sort(sortRecords) where:

function sortRecords(Item1, Item2: Pointer): Integer;
begin
result := CompareStr(TRecInfo(Item1).SiteName, TRecInfo(Item2).SiteName);
end;

HTH,
Harley Pebley

Back to top
Malte Persike
Guest





PostPosted: Wed Feb 11, 2004 3:54 am    Post subject: Re: Index Records Reply with quote

Quote:
Instead of storing the records in an array, use a TList, then sorting is a
matter of Sort(sortRecords) where:

Question: Can plain record variables be stored in a TList?
To my knowledge a TList internally holds pointers to objects. A record
is not an object and thus not persistent, i. e. when the record
variable goes out of scope, any pointer to it will be invalid.
Pete would have to dynamically create instances of TRecInfo with
new/delete to make the TList concept functional.

Besides, I also would advocate using a TList - with TRecInfo as a
class, not a record. Sort of more OO-like.

Regards,
Malte

--

The above e-mail address is not valid. To
contact me, please use my real e-mail address:

malte AT t DASH online DOT de

Back to top
Pete Watts
Guest





PostPosted: Wed Feb 11, 2004 11:13 am    Post subject: Re: Index Records Reply with quote

On Tue, 10 Feb 2004 17:45:13 +0100, Malte Persike <me (AT) privacy (DOT) net>
wrote:

Many thanks,

PW

Quote:
On Tue, 10 Feb 2004 16:02:03 +0000, Pete Watts <pwa334 (AT) aol (DOT) com> wrote:


Hi Pete,

you have to do it with a sort routine that does not compare the
entries of the Grec array but takes the .SiteName property as a
sorting key.
I once implemented a quicksort algorithm for a TList and copy/pasted
the modified code below. Compiling and working are not guaranteed but
I think you'll get the picture. Note that the quicksort is a recursive
type. There are non-recursive implementations which are easier to
understand and debug.

Kind regards,
Malte


Back to top
Harley Pebley
Guest





PostPosted: Wed Feb 11, 2004 6:38 pm    Post subject: Re: Index Records Reply with quote

Quote:
Instead of storing the records in an array, use a TList, then sorting is a
matter of Sort(sortRecords) where:

Question: Can plain record variables be stored in a TList?

Yes.

Quote:
To my knowledge a TList internally holds pointers to objects.

No. A TList holds pointers. Those pointers point to objects, records,
characters or anything else stored in memory. Or it could hold some other
data that fits in a pointer but isn't a pointer. E.g.:

var
someInteger: Integer;
....
someList.Add(Pointer(someInteger));
....
someInteger := Integer(someList.Items[0]);

Quote:
A record is not an object and thus not persistent, i. e. when the record
variable goes out of scope, any pointer to it will be invalid.

Sure, thanks for stating that explictly for the OP. Scoping rules always
apply. One can't store a pointer to a local variable and expect that local
variable to still be valid outside the method. (Well, I guess it could be
expected, but there'll be AVs until the compiler forces a change of
expectations. :-)

Quote:
Pete would have to dynamically create instances of TRecInfo with
new/delete to make the TList concept functional.

Yes. Or create a TRecInfoList class that wraps that function in its
Add/Delete methods.

Quote:
Besides, I also would advocate using a TList - with TRecInfo as a
class, not a record. Sort of more OO-like.

Yes, that is another alternative; and typically records have methods that
operate on them which would then become methods of the object. But now
we're starting to digress into another topic. Wink Yet another option would
be to use a TObjectList. In that case the sort method would cast the items
to the appropriate object type, rather than record type.

Regards,
Harley Pebley

Back to top
Paul
Guest





PostPosted: Thu Feb 12, 2004 11:19 am    Post subject: Re: Index Records Reply with quote

"Pete Watts" <pwa334 (AT) aol (DOT) com> wrote

Quote:
Hi
Can anyone tell me how I may sort or index the record structure so
that the field "Sitename" is in order when I access the data.

Peter


Here is a method of doing this

<---- Start Unit ----->

unit recInfo;

interface
uses
classes;

type
TSiteName = string[30];
TAppName = string[25];
TStieNum = string[6];


TRecInfo = record
SiteName : TSiteName;
AppName : TAppName;
SiteNum : TStieNum;
end;

TRecInfos = array of TRecInfo;


IRecInfoItterator = Interface
['{B821ECE8-A452-4198-A185-E8281A534073}']
procedure first;
procedure next;

function isDone
: boolean;

function currentItem
: TRecInfo;
end;



TRecInfoManager = class
private
fRecInfos : TRecInfos;

FSiteNameIdx : TList;


procedure updateSiteNameIndex
(
siteName : TSiteName;
recInfoIndex : integer
);

public

constructor create;
virtual;

destructor destroy;
override;

procedure add
(
siteName : TSiteName;
AppName : TAppName;
SiteNum : TStieNum
);

function siteNameIndex
: IRecInfoItterator;
end;


implementation

type
TRecInfoItterator = class(TInterfacedObject, IRecInfoItterator )
private
fRecInfos : TRecInfos;
fIndex : TList;

fCurrentItemIdx : integer;

procedure first;
procedure next;

function isDone
: boolean;

function currentItem
: TRecInfo;

public
constructor create
(
RecInfos : TRecInfos;
Index : TList
);
virtual;

end;


// -- TRecInfoItterator

// - private

procedure TRecInfoItterator.first;
begin
fCurrentItemIdx := 0;
end;

procedure TRecInfoItterator.next;
begin
assert( not isDone,
'Logic Error::TRecInfoItterator.next - isDone is true');

inc( fCurrentItemIdx );
end;

function TRecInfoItterator.isDone
: boolean;

begin
result := fCurrentItemIdx = fIndex.Count;
end;

function TRecInfoItterator.currentItem
: TRecInfo;

begin
result := fRecInfos[integer(fIndex.Items[ fCurrentItemIdx ])];
end;

// - public

constructor TRecInfoItterator.create
(
RecInfos : TRecInfos;
Index : TList
);

begin
inherited create;
fRecInfos := RecInfos;
fIndex := Index;
first;

end;




// -- TRecInfoManager

// - private

procedure TRecInfoManager.updateSiteNameIndex
(
siteName : TSiteName;
recInfoIndex : integer
);

var
indexUpdated : boolean;
siteIndexIndex : integer;

begin
indexUpdated := false;
siteIndexIndex := 0;

repeat

if siteIndexIndex = FSiteNameIdx.Count then begin
FSiteNameIdx.Add( pointer( recInfoIndex ));
indexUpdated := true;

end else if (siteName < fRecInfos[integer(FSiteNameIdx.Items[
siteIndexIndex ])].SiteName) then begin
FSiteNameIdx.Insert( siteIndexIndex, pointer( recInfoIndex ));
indexUpdated := true;
end;
inc( siteIndexIndex );

until indexUpdated;
end;


// - public

constructor TRecInfoManager.create;
begin
inherited create;
FSiteNameIdx := TList.create;
end;


destructor TRecInfoManager.destroy;
begin
setLength( fRecInfos, 0 );
FSiteNameIdx.Free;
inherited;
end;


procedure TRecInfoManager.add
(
siteName : TSiteName;
AppName : TAppName;
SiteNum : TStieNum
);

begin
setlength( fRecInfos, length( fRecInfos ) + 1);

fRecInfos[ high( fRecInfos )].SiteName := siteName;
fRecInfos[ high( fRecInfos )].AppName := AppName;
fRecInfos[ high( fRecInfos )].SiteNum := SiteNum;

updateSiteNameIndex( siteName, high( fRecInfos ));
end;


function TRecInfoManager.siteNameIndex
: IRecInfoItterator;

begin
result := TRecInfoItterator.create( fRecInfos, FSiteNameIdx );
end;

end.

<---- End Unit ----->

regards
Paul



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.