Alelo
Alelo

Reputation: 3

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

Upvotes: 0

Views: 218

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596166

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));

Upvotes: 2

Marcodor
Marcodor

Reputation: 5741

Just handle the case when Name property match.

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 Exit(0);
       if L.DateOfBirth < R.DateOfBirth then Exit(1);
       Exit(-1);
     end;
     if L.Name < R.Name then Exit(1);
     Result := -1;
  end));

Upvotes: 0

Related Questions