我正在尝试对标签的值进行排序。我有很多带有整数值的标签。标签被称为Label1,Label2,...,我是通过FindComponent访问的。对存储在数组中的整数值进行排序没有问题,但问题是,在排序之后,我不知道哪个标签有什么值。我的目标是根据标签的值对它们进行排序,这样我就可以得到一个数组,其中的标签是按值排序的。我被困在这一点上:(例如:
Label1.Caption := 10;
Label2.Caption := 4;
Label3.Caption := 7;
for i := 1 to 3
do some_array[i] := StrToInt(TLabel(FindComponent('Label' + IntToStr(i))).Caption);
sortarray(some_array);现在,我已经对数组进行了排序,但我缺少一些排序过程,该过程也会将标签号存储在相应的位置。有人能指给我看吗?
发布于 2011-07-31 23:17:38
创建TLabel控件的数组,而不是创建整数数组。在这里,你可以用与整数数组相同的方式进行排序。实际上,给定一个MyLabel: TLabel,您可以很容易地获得StrToInt(MyLabel.Caption)形式的相关整数。
此外,FindComponent方法的效率不是很高。我会做的
const
ALLOC_BY = 100;
MAGIC_TAG = 871226;
var
i: Integer;
ActualLength: integer;
FLabels: array of TLabel;
begin
SetLength(FLabels, ALLOC_BY);
ActualLength := 0;
for i := 0 to ControlCount - 1 do
if Controls[i] is TLabel then
with TLabel(Controls[i]) do
if Tag = MAGIC_TAG then
begin
if ActualLength = length(FLabels) then
SetLength(FLabels, length(FLabels) + ALLOC_BY);
FLabels[ActualLength] := Controls[i];
inc(ActualLength);
end;
SetLength(FLabels, ActualLength);
SortArray(FLabels) // with respect to the StrToInt(CurLabel.Caption) of each
// CurLabel: TLabel.当然,如果您事先知道标签的数量,则可以跳过块分配。
确保要包含在数组中的每个标签的Tag设置为MAGIC_TAG。
另一种选择是创建一个数组
FLabelDataArray: array of TLabelData;的
type
TLabelData = record
Control: TLabel;
Value: integer;
end;哪里
FLabelDataArray[i].Value := StrToInt(FLabelDataArray[i].Control.Caption);仅计算一次。
发布于 2011-07-31 23:43:33
一种在老的Delphi版本中也有效的快速解决方案是使用TStringList,它有一个Sort方法和一个Objects属性,允许您将一个对象与列表中的每个条目相关联。
请注意,该列表是按字典顺序排序的,因此在转换为字符串时,必须用零填充整数。
var
list: TStringList;
i: integer;
lab: TLabel;
begin
Label1.Caption := '10';
Label2.Caption := '4';
Label3.Caption := '7';
list := TStringList.Create;
try
for i := 1 to 3 do begin
lab := TLabel(FindComponent('Label' + IntToStr(i)));
list.AddObject(Format('%10.10d', [StrToInt(lab.Caption)]), lab);
end;
list.Sort;
for i := 0 to list.Count-1 do
Memo1.Lines.Add(list[i] + #9 + TLabel(list.Objects[i]).Name);
finally
list.Free;
end;
end;输出将为:
0000000004 Label2
0000000007 Label3
0000000010 Label1此外,如果您使用的是list.Sorted := true而不是list.Sort,那么您将获得list上的二进制搜索作为额外奖励(使用list.IndexOf或list.Find)。
编辑:正如Rudy所说,像TLabel这样的可视化组件应该只用于显示数据,而不是用于存储和操作数据。为此,建议使用适当的数据结构,并将程序的逻辑与其用户界面分开。
发布于 2011-07-31 23:19:58
正如Andreas所说,将标签放入动态数组中,而不是对值进行排序。一旦将它们放入这样的数组中,就像这样对它们进行排序:
uses
Generics.Defaults, Generics.Collections;
procedure SortLabels(var Labels: array of TLabel);
var
Comparison: TComparison<TLabel>;
Comparer: IComparer<TLabel>;
begin
Comparison := function(const Left, Right: TLabel): Integer
begin
Result := StrToInt(Left.Caption)-StrToInt(Right.Caption);
end;
Comparer := TDelegatedComparer<TLabel>.Create(Comparison);
TArray.Sort<TLabel>(Labels, Comparer);
end;https://stackoverflow.com/questions/6890249
复制相似问题