Delphi:存储多个TObjectList排序

joh*_*338 3 delphi sorting store tobjectlist

我有一堆TCoordinates存储在TObjectList中.要更快地找到坐标,必须对列表进行排序.问题是iam交替搜索x和y.是否存在存储排序结果的方法,所以我不需要一次又一次地对列表进行排序.

unit uStackoverflowQuestion;

interface

uses
  System.Generics.Collections, System.Generics.defaults;

type
  TCoordinate = class(Tobject)
    public
      x: Integer;
      y: Integer;
  end;

  TMultipleSortedList = class(TObjectlist<TCoordinate>)
    public
      // StoredSortingByX: List;
      // StoredSortingByY: List;
      procedure SortAndStoreByX;
      procedure SortAndStoreByY;
  end;

implementation

procedure TMultipleSortedList.SortAndStoreByX;
begin
  // TODO -cMM: TMultipleSortedList.SortAndStoreByX default body inserted
end;

procedure TMultipleSortedList.SortAndStoreByY;
begin
  // TODO -cMM: TMultipleSortedList.SortAndStoreByY default body inserted
end;

end.
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 5

创建索引图以表示两个不同的订单.这只是一个动态的整数数组.

type
  TListOrder = TArray<Integer>;
Run Code Online (Sandbox Code Playgroud)

当您希望使用该订单阅读项目时,您可以这样做:

function GetItem(Index: Integer; const Order: TListOrder): TItem;
begin
  Result := List[Order[Index]];
end;
Run Code Online (Sandbox Code Playgroud)

这里的关键点是我们不会修改List永远的内容.我们认为这是无序的.相反,我们将订单与容器分开.这允许我们有多个这样的订单.

接下来的问题是如何创建订单.首先使用所有有效索引填充订单:

var
  i: Integer;
  Order: TListOrder;
....
SetLength(Order, List.Count);
for i := 0 to List.Count-1 do
  Order[i] := i;
Run Code Online (Sandbox Code Playgroud)

现在您可以像这样对订单进行排序:

TArray.Sort<Integer>(Order, Comparer);
Run Code Online (Sandbox Code Playgroud)

最后,使用什么作为比较器.这就是魔术发生的地方.

var
  Comparer: IComparer<Integer>;
....
Comparer := 
  function(const Left, Right: Integer): Integer
  var
    LeftItem, RightItem: TItem;
  begin
    LeftItem := GetItem(Left, Order);
    RightItem := GetItem(Right, Order);
    Result := ...; // your compare logic goes here
  end;
Run Code Online (Sandbox Code Playgroud)

就是这样.