Search code examples
delphitobjectlist

How to sort a TObjectList by two (or more) class members?


Assume a very simple object

TPerson = class
private 
    name : String;
    DateOfBirth: TDatetime;
end;
.
.
aList : TObjectList<TPerson>;
.
.

let's say aList is populated like this:

name DateOfBirth
Adam 01/01/2023
Alice 01/02/2023
Adam 01/01/2022

how to sort aList by name and birthdate ?

I tried

  aList.sort(TComparer<TPerson>.Construct(
      function (const L, R: TPerson): integer
      begin
         if L.name=R.name then
            Result:=0
         else if L.name< R.name then
            Result:=1
         else
            Result:=-1;
      end));

this works by name but within the same name i want to sort by DateOfBirth too

i want my object sorted this way:

name DateOfBirth
Adam 01/01/2022
Adam 01/01/2023
Alice 01/02/2023

how can i do it?

btw i'm using Delphi XE10


Solution

  • When two names compare the same, you need to then compare their birthdays and return that result, eg:

    aList.sort(TComparer<TPerson>.Construct(
          function (const L, R: TPerson): integer
          begin
             if L.name = R.name then
             begin
                if L.DateOfBirth = R.DateOfBirth then
                   Result := 0
                else if L.DateOfBirth < R.DateOfBirth then
                   Result := 1
                else
                   Result := -1;
             end
             else if L.name < R.name then
                Result := 1
             else
                Result := -1;
          end));
    

    Alternatively, there are RTL functions available for comparing strings and dates, eg:

    aList.sort(TComparer<TPerson>.Construct(
          function (const L, R: TPerson): integer
          begin
             Result := CompareStr(L.name, R.name);
             if Result = 0 then 
                Result := CompareDate(L.DateOfBirth, R.DateOfBirth);
             Result := -Result;
          end));