Pandora
asked on
using TlistSortCompare to sort Tlist
Hi, I know you can write a custom sorting function for Tlists but I can't work out how you actually define/call it. I have defined Tjob as an object and one of its properties is StartTime :TdateTime. I then have a list JobList:TJobList full of Tjob instances (or pointers to). Please can you tell me how to call Joblist.sort() so that it calls a custom function to sort these all by starttime. I know I have to create a TlistSortCompare function but just not sure how! Thanks v much, P.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you can write it shorter:
function JobListCompare(Item1, Item2: Pointer): Integer;
var
Job1: TJobItem absolute Item1;
Job2: TJobItem absolute Item2;
begin
Result := Job2.StartTime - Job1.StartTime;
end;
function JobListCompare(Item1, Item2: Pointer): Integer;
var
Job1: TJobItem absolute Item1;
Job2: TJobItem absolute Item2;
begin
Result := Job2.StartTime - Job1.StartTime;
end;
Slavak, TDateTime is not an integer. Thus your version will fail. However, the following could be used:
function JobListCompare(Item1, Item2: Pointer): Integer;
var
Job1: TJob absolute Item1;
Job2: TJob absolute Item2;
Temp: TDateTime;
begin
Temp:=Job2.StartTime-Job1. StartTime;
Result:=Ord(Temp>0)-Ord(Te mp<0);
end;
function JobListCompare(Item1, Item2: Pointer): Integer;
var
Job1: TJob absolute Item1;
Job2: TJob absolute Item2;
Temp: TDateTime;
begin
Temp:=Job2.StartTime-Job1.
Result:=Ord(Temp>0)-Ord(Te
end;
I thought the rules were
Item1 < Item2 -> -1
Item1 > Item2 -> 1
Item1 = Item2 -> 0
So shouldn't it be
if Job1.StartTime < Job2.StartTime then
Result := -1
else if Job1.StartTime > Job2.StartTime then
Result := 1
else
Result := 0;
???
which could be re-written as:
Result := -1 + (2 * (Job1.StartTime > Job2.StartTime)) + (Job1.StartTime = Job2.StartTime);
rondi
Item1 < Item2 -> -1
Item1 > Item2 -> 1
Item1 = Item2 -> 0
So shouldn't it be
if Job1.StartTime < Job2.StartTime then
Result := -1
else if Job1.StartTime > Job2.StartTime then
Result := 1
else
Result := 0;
???
which could be re-written as:
Result := -1 + (2 * (Job1.StartTime > Job2.StartTime)) + (Job1.StartTime = Job2.StartTime);
rondi
rondi, it depends whether the newest or the oldest dates should be listed first. However, the basic idea should be visible pretty well. BTW, you forgot to add "Ord()" around your boolean equations, and if you want to do two comparisons why not do it like this:
Result:=Ord(Job1.StartTime >Job2.Star tTime)-Ord (Job1.Star tTime<Job2 .StartTime );
If StartTime is a property which is not a field (e.g. involves a function call), this will be less efficient than storing the result in a temp variable. Since comparisons are called quite often when sorting, I think that speed could become an issue.
Result:=Ord(Job1.StartTime
If StartTime is a property which is not a field (e.g. involves a function call), this will be less efficient than storing the result in a temp variable. Since comparisons are called quite often when sorting, I think that speed could become an issue.
ASKER
Call me old fashioned but I'm gonna go for the long hand version! Thanks v much for all your comments, I would never have got the 'absolute' part! Best wishes, P.
Pandora, the "absolute" part is not an absolute neccesity but rater to make things easier. You could also use typecasts to cast the pointers to your TJob classes, but the result would be the same.
ASKER
Gotcha - thanks v much! P :)
Avon: I stand corrected :)
var
begin
if TJobItem(Item1).StartTime>
end;