8

我经常发现我需要“调整” aa 的大小TStringList以恰好容纳 N 个元素,或者向列表中添加额外的空字符串,或者删除不必要的字符串。

在 C++ STL 容器上,我可以使用该resize方法,但由于该方法似乎不存在,因此我通常会这样做(警告:伪代码!)。

list.beginUpdate;

while list.Count < requiredSize do
begin
   list.add('');
end;

while list.Count > requiredSize do
begin
   list.delete(list.count-1);
end;

list.endUpdate;

有没有我忽略的更简单的方法?

4

4 回答 4

7

从 的实现来看TStringList.Assign,没有更好的方法可以做到这一点。他们基本上Clear是一一调用和添加字符串。

您当然应该将代码放入实用程序方法中:

procedure ResizeStringList(List : TStrings; ANewSize: Integer);
begin
...
end;

或者,您可以使用类助手使您的方法看起来是其TStringList自身的一部分。

于 2014-01-13T10:03:03.413 回答
3

你问题中的方法是你能做的最好的。如果你使用类助手,你可以让它更干净。例如:

type
  TStringsHelper = class helper for TStrings
    procedure SetCount(Value: Integer);
  end;

procedure TStringsHelper.SetCount(Value: Integer);
begin
  BeginUpdate;
  try
    while Count<Value do
      Add('');
    while Count>Value do
      Delete(Count-1);
  finally
    EndUpdate;
  end;
end;

然后你可以写:

List.SetCount(requiredSize);
于 2014-01-13T10:09:11.080 回答
3

Capacity属性几乎是理想的,因为它将在内部数组中分配正确数量的条目。但是,它有一个不幸的缺点:

  • 新分配的内存未初始化。
  • 元素的数量Strings.Count不会更新。

由于 Delphi 组件体系结构引用了基本类型TStrings,因此您可以提供可以支持更有效的调整大小功能的具体子类。例如,考虑以下实现TList.SetCount

procedure TList.SetCount(NewCount: Integer);
var
  I: Integer;
begin
  if (NewCount < 0) or (NewCount > MaxListSize) then
    Error(@SListCountError, NewCount);
  if NewCount > FCapacity then
    SetCapacity(NewCount);
  if NewCount > FCount then
    FillChar(FList^[FCount], (NewCount - FCount) * SizeOf(Pointer), 0)
  else
    for I := FCount - 1 downto NewCount do
      Delete(I);
  FCount := NewCount;
end;

更新容量后,如果有新分配的内存,则使用 初始化FillChar。这比一次添加/删除一项要有效得多。

因此,您可以提供自己独立的子类具体实现,或者简单地复制包含适当方法TStrings的 Delphi 的副本。TStringListSetCount

尽管如此,我发现这部分代码不太可能会遇到任何性能问题,因此您自己的解决方案包含在适当的实用方法中就足够了。大卫的回答也很好,虽然我个人认为“类助手”功能没有那么有用。实现类助手的“旧方式”更加通用。

于 2014-01-13T12:30:51.537 回答
0
var
    List:  TStringList;

Assert(requiredSize >= 0);
if requiredSize > List.Count then
    List.Capacity := requiredSize
else
    while List.Count > requiredSize do
        List.Delete(List.Count - 1);
于 2014-01-13T12:20:01.630 回答