Monday 30 July 2018

Delphi - Sort an Object List by Property


Below is a quick example of how to use the .Sort function. In this case i have two objects declared in the Type seciton. On form create i am creating an instance of TPersons, then creating a number of dummy TPersons and adding them to my 'Persons'. Then behind a button click i am sorting the order of the Persons using the following code:

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


To recreate this simple example, drop a memo and a button on a form. The make your code look like this:

unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, Generics.Collections, FMX.ScrollBox,
  FMX.Memo, Generics.Defaults;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TPerson = class(TObject)
    Name: string;
    Age: integer;
  end;

  TPersons = class(TObjectList<TPerson>)
  end;


var
  Form2: TForm2;

implementation

{$R *.fmx}

var
  Persons: TPersons;


procedure TForm2.Button1Click(Sender: TObject);
var
  Person: TPerson;
  I: Integer;
begin
  for Person in Persons do
  begin
    Persons.Sort(TComparer<TPerson>.Construct(
      function (const L,R: TPerson): integer
      begin
        if L.Name > R.Name then
          Result := 1
        else if L.Name < R.Name then
          Result := -1
        else
          Result := 0;
      end
      ));
  end;

  for I := 0 to Persons.Count -1 do
  begin
    Memo1.Lines.Add(Persons[I].Name);
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  Person: TPerson;
  I: Integer;
begin
  Persons := TPersons.Create(true);

  Person := TPerson.Create;
  Person.Name := 'John';
  Person.Age := 34;
  Persons.Add(Person);

  Person := TPerson.Create;
  Person.Name := 'James';
  Person.Age := 31;
  Persons.Add(Person);

  Person := TPerson.Create;
  Person.Name := 'Sally';
  Person.Age := 21;
  Persons.Add(Person);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  Persons.Free;
end;

end.

No comments:

Post a Comment