(我知道这是一年后,但仍然有用的东西。)
Skamradt 的填充整数值的建议假设您将使用字符串比较进行排序。这会很慢。为每个插入调用 format(),速度仍然较慢。相反,您想要进行整数比较。
你从一个记录类型开始:
TExample = record
SortOrder : integer;
SomethingElse : string;
end;
您没有说明记录的存储方式,或者排序后您希望如何访问它们。所以让我们假设你把它们放在一个动态数组中:
var MyDA Array of TExample;
...
SetLength(MyDA,NewSize); //allocate memory for the dynamic array
for i:=0 to NewSize-1 do begin //fill the array with records
MyDA[i].SortOrder := SomeInteger;
MyDA[i].SomethingElse := SomeString;
end;
现在您要按整数值 SortOrder 对该数组进行排序。如果您想要的是 TStringList (因此您可以使用 ts.Find 方法),那么您应该将每个字符串添加到列表中并将 SortOrder 添加为指针。然后按指针排序:
var tsExamples: TStringList; //declare it somewhere (global or local)
...
tsExamples := tStringList.create; //allocate it somewhere (and free it later!)
...
tsExamples.Clear; //now let's use it
tsExamples.sorted := False; //don't want to sort after every add
tsExamples.Capacity := High(MyDA)+1 //don't want to increase size with every add
//an empty dynamic array has High() = -1
for i:=0 to High(MyDA) do begin
tsExamples.AddObject(MyDA[i].SomethingElse,TObject(MyDA[i].SortOrder));
end;
请注意将 Integer SortOrder 转换为 TObject 指针的技巧,该指针存储在 TStringList.Object 属性中。 (这取决于整数和指针大小相同的事实。)我们必须在某个地方定义一个函数来比较 TObject 指针:
function CompareObjects(ts:tStringList; Item1,Item2: integer): Integer;
var i,j: integer;
begin
Result := integer(ts.Objects[i]) - integer(ts.Objects[j];
end;
现在,我们可以通过调用 .CustomSort 而不是 .Sort 对 .Object 上的 tsList 进行排序(这将根据字符串值进行排序。)
tsExample.CustomSort(@CompareObjects); //Sort the list
TStringList 现在已排序,因此您可以从 0 迭代到 .Count-1 并按排序顺序读取字符串。
但是假设您不想要一个 TStringList,而只是一个按排序顺序排列的数组。或者,记录包含的数据多于本示例中的一个字符串,并且您的排序顺序更复杂。您可以跳过添加每个字符串的步骤,只需将数组索引添加为 TList 中的 Items。以相同的方式执行上述所有操作,除了使用 TList 而不是 TStringList:
var Mlist: TList; //a list of Pointers
...
for i:=0 to High(MyDA) do
Mlist.add(Pointer(i)); //cast the array index as a Pointer
Mlist.Sort(@CompareRecords); //using the compare function below
function CompareRecords(Item1, Item2: Integer): Integer;
var i,j: integer;
begin
i := integer(item1); //recover the index into MyDA
j := integer(item2); // and use it to access any field
Result := SomeFunctionOf(MyDA[i].SomeField) - SomeFunctionOf(MyDA[j].SomeField);
end;
现在 Mlist 已排序,将其用作查找表以按排序顺序访问数组:
for i:=0 to Mlist.Count-1 do begin
Something := MyDA[integer(Mlist[i])].SomeField;
end;
当 i 遍历 TList 时,我们按排序顺序取回数组索引。我们只需要将它们转换回整数,因为 TList 认为它们是指针。
我喜欢这样做,但您也可以通过添加数组元素的地址而不是它的索引来将真正的指针指向 TList 中的数组元素。然后要使用它们,您可以将它们转换为指向 TExample 记录的指针。这就是 Barry Kelly 和 CoolMagic 在他们的回答中所说的。