【问题标题】:Delphi TStringList CustomSort on Name [closed]Delphi TStringList CustomSort on Name [关闭]
【发布时间】:2014-02-04 15:41:15
【问题描述】:

我尝试在名称部分对 TStringList 进行排序。为此,我使用 customSort 方法。

我给你看一个小例子:

    function CompareString(List : TStringList; Index1, Index2 : integer) : integer;
    begin
        result := AnsiCompareText(List.Names[Index1], List.Names[Index2]);
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        Memo2.Clear;
        Liste.CustomSort(CompareString);     
        Memo2.Lines.Append(Liste.GetText)
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        Liste := TStringList.Create;
        Liste.Append('INFOS_NEGOCE=NUM_CDE');
        Liste.Append('INFOS_NEGOCE=DATE_CDE');
        Liste.Append('INFOS_NEGOCE=NOM_REPERTOIRE_ENT');
        Liste.Append('INFOS_NEGOCE=NOM_CONTACT');     
        Memo1.Lines.Clear;
        Memo1.Lines.Append(Liste.GetText)
    end;

排序给我这个结果:

INFOS_NEGOCE=NOM_REPERTOIRE_ENT

INFOS_NEGOCE=NOM_CONTACT

INFOS_NEGOCE=NUM_CDE

INFOS_NEGOCE=DATE_CDE

我认为排序不会改变行的顺序(名称总是INFOF_NEGOCE)。

【问题讨论】:

  • 你期待什么结果?另外,你知道TStringList 上有一个Sort 方法吗?
  • 你有什么问题?

标签: delphi sorting tstringlist


【解决方案1】:

排序是使用 QuickSort 完成的。这意味着相同项目的顺序(如排序所见)是未定义的。

Quicksort - Repeated Elements

【讨论】:

  • @mbratch,但排序例程只查找名称部分并且它们是相同的。
  • 是的,你是对的,这是一个快速排序。所以我没有解决方案。我会改变我的问题的方式。
【解决方案2】:
function CompareString(List : TStringList; Index1, Index2 : integer) : integer;
begin
  Result := AnsiCompareText(List.Names[Index1], List.Names[Index2]);
  // If you want to sort equal strings then on the Values
  if Result = 0 then Result := AnsiCompareText(List.ValueFromIndex[Index1], List.ValueFromIndex[Index2]);
  // Or if you want to keep the original order
  { if Result = 0 then Result := Index1-Index2; --- qv : this won't work!}
end;

如果Names 相等,您的代码会将Result 设置为0。如果它们相等,请选择您要使用哪些附加条件对同名项目进行排序。


正如 Uwe Raabe 正确观察到的那样,“原始顺序”是行不通的。

但一切都没有丢失。通常,不使用 Tstringlist 中包含的对象。如果它可用,那么就在排序之前,尝试

for i := 0 to pred(List.Count) do List.Objects[i] := TObject(i);

排序变成了

function CompareString(List : TStringList; Index1, Index2 : integer) : integer;
begin
  Result := AnsiCompareText(List.Names[Index1], List.Names[Index2]);
  // If you want to sort equal strings then on the Values
  if Result = 0 then Result := AnsiCompareText(List.ValueFromIndex[Index1], List.ValueFromIndex[Index2]);
  // Or if you want to keep the original order
  if Result = 0 then Result := integer(List.Objects[Index1])-integer(List.Objects[Index2]);
end;

但如果让我们知道“正确”顺序应该是什么的秘密,那就容易多了。

【讨论】:

  • 更好,但结果不正确。
  • Index1 和 Index2 不代表原始顺序。它们给出了当前排序迭代的当前顺序,这是高度易变的。
  • @UweRaabe : 这个应该...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 2012-12-05
相关资源
最近更新 更多