Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Create your online store today with Shopify

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth

Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Disclosure: My content contains affiliate links.

43,236 questions

56,139 answers

573 users

How to sort a list of records that contain nested records using custom comparison logic in Pascal

1 Answer

0 votes
program SortNestedStructs;

{$mode objfpc}{$H+}{$MODESWITCH ADVANCEDRECORDS}{$WARN 6058 OFF}{$WARN 5024 OFF}

uses
  SysUtils, Generics.Collections, Generics.Defaults;

type
  TAddress = record
    City: string;
    ZipCode: Integer;
  end;

  TPerson = record
    Name: string;
    Age: Integer;
    Address: TAddress;
  end;

  TPersonList = specialize TList<TPerson>;
  TPersonComparer = class(TInterfacedObject, specialize IComparer<TPerson>)
  public
    function Compare(constref Left, Right: TPerson): Integer;
  end;

{ TPersonComparer }

function TPersonComparer.Compare(constref Left, Right: TPerson): Integer;
begin
  // Primary Sort: City (Ascending)
  Result := CompareText(Left.Address.City, Right.Address.City);
  if Result <> 0 then Exit;

  // Secondary Sort: ZipCode (Ascending)
  Result := Left.Address.ZipCode - Right.Address.ZipCode;
  if Result <> 0 then Exit;

  // Tertiary Sort: Age (Ascending) - Fixes tie-breaker order
  Result := Left.Age - Right.Age;
end;

var
  People: TPersonList;
  P: TPerson;
  Person: TPerson;
  Comparer: specialize IComparer<TPerson>;
begin
  People := TPersonList.Create;
  Comparer := TPersonComparer.Create;
  try
    // Add sample data
    Person.Name := 'Alice';   Person.Age := 35; Person.Address.City := 'New York'; Person.Address.ZipCode := 8001;
    People.Add(Person);

    Person.Name := 'Bob';     Person.Age := 45; Person.Address.City := 'Boston';   Person.Address.ZipCode := 2108;
    People.Add(Person);

    Person.Name := 'Charlie'; Person.Age := 25; Person.Address.City := 'Austin';   Person.Address.ZipCode := 14006;
    People.Add(Person);

    Person.Name := 'Diana';   Person.Age := 30; Person.Address.City := 'New York'; Person.Address.ZipCode := 10001;
    People.Add(Person);
      
    Person.Name := 'Eve';     Person.Age := 28; Person.Address.City := 'Austin';   Person.Address.ZipCode := 14006;
    People.Add(Person);

    // Sort list
    People.Sort(Comparer);

    // Output results
    for P in People do
      WriteLn(Format('%-8s | Age: %d | City: %-8s | Zip: %d', 
        [P.Name, P.Age, P.Address.City, P.Address.ZipCode]));
  finally
    Comparer := nil;
    People.Free;
  end;
end.
 
 
 
{
run:
 
Charlie  | Age: 25 | City: Austin   | Zip: 14006
Eve      | Age: 28 | City: Austin   | Zip: 14006
Bob      | Age: 45 | City: Boston   | Zip: 2108
Alice    | Age: 35 | City: New York | Zip: 8001
Diana    | Age: 30 | City: New York | Zip: 10001
 
}

 



answered Sep 1 by avibootz
edited Sep 1 by avibootz

Related questions

...