Delphi TList<T> 复制到另一个 TList 中?

Vol*_*hbb 2 delphi tlist

我想知道是否有任何安全的方法可以将 TList 元素复制到任何其他 TList 到特定位置和特定长度。我应该将 list1 的元素分配给 list2 还是有任何功能我不知道处理更准确?

感谢您抽出宝贵时间。

Enn*_*nny 5

我会使用AddRange在末尾附加项目或使用InsertRange在特定索引上插入项目。


Del*_*ics 5

如果您的意图是REPLACE项目而不是在给定位置插入它们,那么答案是没有直接机制,迭代分配是使用的方法。

for i := 1 to maxItems do
  dest[ insertPos + i - 1] := src[ i - 1 ];
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您应该考虑添加的项目多于目标列表空间的情况。这是否意味着只替换“适合”的项目,添加额外的项目以“腾出空间”或根本不分配任何项目(除非所有项目都适合),这是一个只有您的要求才能回答的问题。

但是,如果你的意图是INSERT项到目标列表中,那么可以使用的组合InsertRange()复制()连同内部的<T>阵列由源列表维护。例如,使用TList<String> 的两个实例:

var
  src, dest: TList<String>;
  insertIndex, maxItems: Integer;

dest.InsertRange( insertIndex, Copy( src.List, 0, maxItems ) );
Run Code Online (Sandbox Code Playgroud)

要插入整个 src列表,您不需要使用Copy()但可以直接在InsertRange()方法中引用源列表:

dest.InsertRange( insertIndex, src );
Run Code Online (Sandbox Code Playgroud)

性能说明:

如果源列表很大和/或添加的子项数量很少,则使用Copy()是一项潜在的昂贵操作。但是,将项目实际插入目标列表是非常有效的,因为InsertRange()方法能够在单个操作中为目标列表中的新项目腾出空间,然后将新项目插入为它们创建的空间中,因此对于添加的更多项目,它可能仍然被证明是最有效的。

另一种方法是迭代地单独插入源项:

for i := 1 to maxItems do
  dest.Insert( insertIndex, src[i - 1]);
Run Code Online (Sandbox Code Playgroud)

虽然这避免了复制插入的数组项,但如果目标列表很大并且插入的项数更多,则迭代插入本身可能效率低下,因为必须为每次插入分别为目标列表中的每个项腾出空间(尽管通过显式计算和预分配目标列表的容量可以显着改善这种潜在影响)。

例如,如果您将 1000 个项目列表中的 100 个项目插入到 2000 个项目列表的(确切)中间:

InsertRange( Copy() )       Copy 100 items into an intermediate array
                            Moves 1000 items in the dest list to make room for 2100 (total)
                            Inserts 100 items into the 'blank' space

Iterative insert            100 repetitions of:
                               Move 1000 items in the dest list to make room for 1 more
                               Inserts 1 item
Run Code Online (Sandbox Code Playgroud)

对于插入 100 个项目,InsertRange()可能是最有效的。相比之下,如果仅插入源列表中的单个项目,则InsertRange()方法可能会产生过多的开销。

我认为应该很明显,不同的启动条件将决定两种方法中哪一种最有效,如果性能是一个重要问题,应该考虑。