首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi标签值排序

问Delphi标签值排序
EN

Stack Overflow用户
提问于 2011-07-31 23:11:49
回答 4查看 1.8K关注 0票数 2

我正在尝试对标签的值进行排序。我有很多带有整数值的标签。标签被称为Label1,Label2,...,我是通过FindComponent访问的。对存储在数组中的整数值进行排序没有问题,但问题是,在排序之后,我不知道哪个标签有什么值。我的目标是根据标签的值对它们进行排序,这样我就可以得到一个数组,其中的标签是按值排序的。我被困在这一点上:(例如:

代码语言:javascript
复制
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);

现在,我已经对数组进行了排序,但我缺少一些排序过程,该过程也会将标签号存储在相应的位置。有人能指给我看吗?

EN

回答 4

Stack Overflow用户

发布于 2011-07-31 23:17:38

创建TLabel控件的数组,而不是创建整数数组。在这里,你可以用与整数数组相同的方式进行排序。实际上,给定一个MyLabel: TLabel,您可以很容易地获得StrToInt(MyLabel.Caption)形式的相关整数。

此外,FindComponent方法的效率不是很高。我会做的

代码语言:javascript
复制
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。

另一种选择是创建一个数组

代码语言:javascript
复制
FLabelDataArray: array of  TLabelData;

的

代码语言:javascript
复制
type
  TLabelData = record
    Control: TLabel;
    Value: integer;
  end;

哪里

代码语言:javascript
复制
FLabelDataArray[i].Value := StrToInt(FLabelDataArray[i].Control.Caption);

仅计算一次。

票数 1
EN

Stack Overflow用户

发布于 2011-07-31 23:43:33

一种在老的Delphi版本中也有效的快速解决方案是使用TStringList,它有一个Sort方法和一个Objects属性,允许您将一个对象与列表中的每个条目相关联。

请注意,该列表是按字典顺序排序的,因此在转换为字符串时,必须用零填充整数。

代码语言:javascript
复制
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;

输出将为:

代码语言:javascript
复制
0000000004   Label2
0000000007   Label3
0000000010   Label1

此外,如果您使用的是list.Sorted := true而不是list.Sort,那么您将获得list上的二进制搜索作为额外奖励(使用list.IndexOf或list.Find)。

编辑:正如Rudy所说,像TLabel这样的可视化组件应该只用于显示数据,而不是用于存储和操作数据。为此,建议使用适当的数据结构,并将程序的逻辑与其用户界面分开。

票数 1
EN

Stack Overflow用户

发布于 2011-07-31 23:19:58

正如Andreas所说,将标签放入动态数组中,而不是对值进行排序。一旦将它们放入这样的数组中,就像这样对它们进行排序:

代码语言:javascript
复制
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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6890249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档