Reputation: 59
I have to make an highscore memo for my school in Delphi 6. Is there a way to sort the MemoLines on numbers or alphabet?
I use 4 Tedits and 1 TMemo. If the game ends, my code will check who has got the highest score. This is how to check if Player1 got a higher score then player2:
if in1>p2in1 then begin
highscore.naammemo.Lines.Add(Speler1.Caption);
highscore.saldomemo.Lines.Add(Saldo1.Text);
end;
How do I create a code for the TMemo to sort the highest score of each game?
Upvotes: 3
Views: 5886
Reputation: 125718
Here's some sample code that will let you experiment with sorting. It uses a text value and a number on each line, separated by a tab character (#9
). There's code at the start of each button click handler that resets the text to the same starting value, so you can see the effects. The first button (btnNameSort
) sorts by the text values using the standard TStringList.Sort
, and the second (btnScoreSort
) sorts by the numeric value using a TListSortCompare
custom sort function.
// Simply uses TStringList.Sort to sort in the default (alpha) order
procedure TForm1.btnNameSortClick(Sender: TObject);
var
SL: TStringList;
begin
InitMemoLines;
SL := TStringList.Create;
try
Memo1.Lines.BeginUpdate;
try
SL.Assign(Memo1.Lines);
SL.Sort;
Memo1.Lines.Assign(SL);
finally
Memo1.Lines.EndUpdate;
end;
finally
SL.Free;
end;
end;
// Sorts by extracting the text after the tab character on the lines
// being compared, converting to numbers, and comparing the numbers.
// Called by using SL.CustomSort in the btnScoreSortClick event
// below.
//
// NOTE: Will obviously fail if the lines don't contain a tab, or
// if the content after the tab can't be converted to a numeric.
// Neither of those cases is handled here for brevity.
function NumberedListSort(List: TStringList; Index1, Index2: Integer): Integer;
var
Line1, Line2: string;
Num1, Num2: Integer;
begin
Line1 := List[Index1];
Line2 := List[Index2];
Num1 := StrToInt(Copy(Line1, Pos(#9, Line1) + 1, 255));
Num2 := StrToInt(Copy(Line2, Pos(#9, Line2) + 1, 255));
Result := Num1 - Num2;
end;
// Calls NumberedListSort to sort by the numbers on the right end
// of each line in the memo
procedure TForm1.btnScoreSortClick(Sender: TObject);
var
SL: TStringList;
begin
InitMemoLines;
SL := TStringList.Create;
try
Memo1.Lines.BeginUpdate;
try
SL.Assign(Memo1.Lines);
SL.CustomSort(NumberedListSort);
Memo1.Lines.Assign(SL);
finally
Memo1.Lines.EndUpdate;
end;
finally
SL.Free;
end;
end;
// Calls InitMemoLines to set the starting content of the memo
procedure TForm1.FormCreate(Sender: TObject);
begin
InitMemoLines;
end;
// Generates content of memo
procedure TForm1.InitMemoLines;
var
i: Integer;
begin
Memo1.Lines.Clear;
for i := 1 to 10 do
Memo1.Lines.Append(Format('Line ' + Chr(90 - i) + #9 + ' %d', [i]));
end;
Upvotes: 4
Reputation: 613053
I think the simplest way would be something along these lines:
TStringList
instance.CustomSort
on the TStringList
instance, passing an appropriate sort compare function.Steps 1 and 3 are simple calls to Assign
. So step 1 would be:
StringList.Assign(Memo.Lines);
And step 3 would be:
Memo.Lines.Assign(StringList);
Step 2 is the tricky bit. You've got to provide a compare function of this type:
TStringListSortCompare = function(List: TStringList;
Index1, Index2: Integer): Integer;
Your function will look like this:
function MySortCompare(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := MyCompareStrings(List[Index1], List[Index2]);
end;
where MyCompareStrings
is a function that compares two strings according to your rules. The return value of that function follows the usual convention for a compare function. Negative means less than, positive means greater than and zero means equal.
Of course, you can write the logic directly inline to MySortCompare
if you prefer.
Upvotes: 5