我有一堆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.
答案 0 :(得分:5)
创建索引图以表示两个不同的订单。这只是一个动态的整数数组。
type
TListOrder = TArray<Integer>;
当您希望使用该订单阅读项目时,您可以这样做:
function GetItem(Index: Integer; const Order: TListOrder): TItem;
begin
Result := List[Order[Index]];
end;
这里的关键点是我们不会修改List
的内容。我们认为这是无序的。相反,我们将订单与容器分开。这允许我们有多个这样的订单。
下一个问题是如何创建订单。首先使用所有有效索引填充订单:
var
i: Integer;
Order: TListOrder;
....
SetLength(Order, List.Count);
for i := 0 to List.Count-1 do
Order[i] := i;
现在您可以按顺序对订单进行排序:
TArray.Sort<Integer>(Order, Comparer);
最后,使用什么作为比较器。这就是魔术发生的地方。
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;
就是这样。
答案 1 :(得分:0)
如果列表中的对象没有更改,您可以使用TList&lt;&gt;存储对象的附加引用,而不是David Heffernan建议的整数数组。它在访问时间方面有一个小优势。