在Delphi中对备忘录进行排序

3

我需要在Delphi 6中为学校制作一个高分备忘录。 有没有一种方法可以按数字或字母顺序对MemoLines进行排序?

我使用4个TEdit和1个TMemo。 如果游戏结束,我的代码将检查谁得到了最高分。 以下是如何检查Player1是否比player2得分更高的方法:

if in1>p2in1 then begin
  highscore.naammemo.Lines.Add(Speler1.Caption);
  highscore.saldomemo.Lines.Add(Saldo1.Text);
end;

我应该如何为TMemo创建一个代码以对每个游戏的最高分数进行排序?


我认为你应该考虑创建一个数据对象并对这些数据对象进行排序。然后,你应该将已经排序的数据对象打印到字符串列表中。你现在正陷入了"强字符串类型"的不良实践中,只使用内置数据类型(尤其是字符串),而没有考虑创建自己的记录或类。 - undefined
2个回答

4
我认为最简单的方法是这样的:
  1. 将备忘录中的内容传输到一个TStringList实例中。
  2. TStringList实例上调用CustomSort,并传递适当的排序比较函数。
  3. 将内容传回备忘录。
步骤1和3只需要调用Assign。所以第一步应该是:
StringList.Assign(Memo.Lines);

第三步是:
Memo.Lines.Assign(StringList);

步骤2是比较棘手的部分。您需要提供一个这样类型的比较函数:
TStringListSortCompare = function(List: TStringList; 
  Index1, Index2: Integer): Integer;

您的函数应该是这样的:
function MySortCompare(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := MyCompareStrings(List[Index1], List[Index2]);
end;

这里的 MyCompareStrings 是一个根据你的规则比较两个字符串的函数。该函数的返回值遵循比较函数的通常惯例。负数表示小于,正数表示大于,零表示相等。

当然,如果你愿意的话,也可以直接在 MySortCompare 中编写逻辑。


非常感谢您的出色回答,但是我不明白我应该在我的项目中放置步骤1-3的代码在哪里。 - undefined
好吧,这是你的代码,不是我的。我们几乎无法指导你在哪里写什么,因为只有你能看到你的代码。你问如何根据自定义顺序对备忘录进行排序。在需要执行此操作的代码位置,插入步骤1-3。你应该集中精力理解代码。 - undefined
1
我本以为你会有更巧妙的方式,David...;-) 顺便说一下+1 - undefined
1
@NGLN 看起来我对更简洁的方式的期望是不现实的!!;-) 你的记忆力真是像大象一样强大。我得小心我在这里说什么,否则会给我带来麻烦!!:-) - undefined

4
这里有一些示例代码,可以让您尝试排序。它使用每行的文本值和数字,由制表符 (#9) 分隔。每个按钮点击处理程序的开头都有代码将文本重置为相同的起始值,以便您可以看到效果。第一个按钮(btnNameSort)使用标准的 TStringList.Sort 按文本值排序,第二个按钮(btnScoreSort)使用一个TListSortCompare自定义排序函数按数值排序。
// 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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接