• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 222
  • Last Modified:

Sorting record structure

Hi,


I am using a simple record structure:

type
  KeyAnalyze=Record
    Key:string;
    Num:integer;
end;

After populating the records, How can I sort in descending order by the "Num" value?
0
Esopo
Asked:
Esopo
  • 3
  • 2
1 Solution
 
kretzschmarCommented:
where do you populate the records?
0
 
EsopoAuthor Commented:
var
  KeyArray: array of KeyAnalyze;

...
then, within a loop:

           SetLength(KeyArray, length(KeyArray) +1);
           KeyArray[length(KeyArray) -1].Key:= WhateverString;
           KeyArray[length(KeyArray) -1].Num:= WhateverNumber;

*********

Now I need to sort the array of records by the Num value so that I can return the records organized in descending order to the user.

Makes sense?
0
 
TheRealLokiSenior DeveloperCommented:
here's an example I wrote for you

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  KeyAnalyze = Record
    Key:string;
    Num:integer;
end;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    procedure SortMyArrayByNum;
    procedure SortMyArrayByNumDescending;
    { Private declarations }
  public
    { Public declarations }
      KeyArray: array of KeyAnalyze;
      procedure AddRecord(Key_: string; Num_: integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}


procedure TForm1.SortMyArrayByNum;
    var
        NoSwap: boolean;
        i: integer;
        Key_: string;
        Num_: integer;
    begin
        Repeat
            NoSwap := true;
            For i := 0 to length(KeyArray) - 2 do // -2 because we do +1 later on
            begin
                if KeyArray[i].Num > KeyArray[i+1].Num then
                begin //we have to switch.
                    NoSwap := False; //We have to tell the sort we aren't done.
                    Key_ := KeyArray[i].Key; //store
                    Num_ := KeyArray[i].Num; //store
                    KeyArray[i].Key := KeyArray[i+1].Key; //put the other in its place.
                    KeyArray[i].Num := KeyArray[i+1].Num; //put the other in its place.
                    KeyArray[i+1].Key := Key_; //Put the stored value
                    KeyArray[i+1].Num := Num_; //Put the stored value
                end;
            end;
        //if there has been even one switch, NoSwap is false;
        Until NoSwap
    end;

procedure TForm1.SortMyArrayByNumDescending;
    var
        NoSwap: boolean;
        i: integer;
        Key_: string;
        Num_: integer;
    begin
        Repeat
            NoSwap := true;
            For i := 0 to length(KeyArray) - 2 do // -2 because we do +1 later on
            begin
                if KeyArray[i].Num < KeyArray[i+1].Num then
                begin //we have to switch.
                    NoSwap := False; //We have to tell the sort we aren't done.
                    Key_ := KeyArray[i].Key; //store
                    Num_ := KeyArray[i].Num; //store
                    KeyArray[i].Key := KeyArray[i+1].Key; //put the other in its place.
                    KeyArray[i].Num := KeyArray[i+1].Num; //put the other in its place.
                    KeyArray[i+1].Key := Key_; //Put the stored value
                    KeyArray[i+1].Num := Num_; //Put the stored value
                end;
            end;
        //if there has been even one switch, NoSwap is false;
        Until NoSwap
    end;

procedure TForm1.FormCreate(Sender: TObject);
    var
        i: integer;
    begin
        AddRecord('A', 4);
        AddRecord('B', 2);
        AddRecord('C', 1);
        AddRecord('D', 3);
//        SortMyArrayByNum;
        SortMyArrayByNumDescending;
        for i := 0 to length(KeyArray) - 1 do
          memo1.lines.add( KeyArray[i].Key + ' ' + IntToStr(KeyArray[i].Num));
    end;

procedure TForm1.AddRecord(Key_: string; Num_: integer);
    begin
        SetLength(KeyArray, length(KeyArray) + 1);

        KeyArray[length(KeyArray) -1].Key:= Key_;
        KeyArray[length(KeyArray) -1].Num:= Num_;
    end;

end.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
EsopoAuthor Commented:
Thank you!

I was hoping for a SortStructure() kind of function from Delphi, but your is just as good.
0
 
TheRealLokiSenior DeveloperCommented:
well if you have the enterprise version you might be able to use TBaseArray and override the Sort() method,
otherwise you could use a TObjectList and a class to do the same thing (see below)

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  contnrs; // needed for TObjectList which automatically frees list items

type
  TKeyAnalyze = class
  public
    Key:string;
    Num:integer;
    Constructor Create(Key_: string; Num_: integer);
end;

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

var
  Form2: TForm2;
  function SortByNum(Item1, Item2: Pointer): Integer;
  function SortByNumDescending(Item1, Item2: Pointer): Integer;


IMPLEMENTATION

{$R *.DFM}

{ sort routines }

function SortByNum(Item1, Item2: Pointer): Integer;
    begin
        if TKeyAnalyze(Item1).Num < TKeyAnalyze(Item2).Num then
          result := -1
        else
          if TKeyAnalyze(Item1).Num > TKeyAnalyze(Item2).Num then
          result := 1
        else
          result := 0;
    end;

function SortByNumDescending(Item1, Item2: Pointer): Integer;
    begin
        if TKeyAnalyze(Item1).Num > TKeyAnalyze(Item2).Num then
          result := -1
        else
          if TKeyAnalyze(Item1).Num < TKeyAnalyze(Item2).Num then
          result := 1
        else
          result := 0;
    end;

{ KeyAnalyze }

constructor TKeyAnalyze.Create(Key_: string; Num_: integer);
    begin
        inherited Create;
        Key := Key_;
        Num := Num_;
    end;

{ Form }

procedure TForm2.FormCreate(Sender: TObject);
    var
        i: integer;
    begin
        MyList := TObjectList.Create;
        MyList.add( TKeyAnalyze.Create('A', 4) );
        MyList.add( TKeyAnalyze.Create('B', 2) );
        MyList.add( TKeyAnalyze.Create('C', 1) );
        MyList.add( TKeyAnalyze.Create('D', 3) );
        MyList.Sort(SortByNumDescending);
        for i := 0 to MyList.Count - 1 do
          memo1.lines.add( TKeyAnalyze(MyList[i]).Key + ' ' + IntToStr( TKeyAnalyze(MyList[i]).Num) );
    end;

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

end.
0
 
EsopoAuthor Commented:
Very interesting. Is this kind of power that makes me proud of using Delphi :D
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now