Delphi TList<T> Copy into another TList?

风流意气都作罢 提交于 2019-12-10 11:41:35

问题


I would like to know if there is any safe way to copy the TList elements into any other TList to a specific position and with a specific length. Should I just assign the elements of the list1 to list2 or is there any functionality out there I'm not aware of that handles that more accurate?

Thanks for taking your time.


回答1:


If your intention is to REPLACE items rather than to insert them at a given position, then the answer is that there is no direct mechanism and iterative assignment is the approach to use.

for i := 1 to maxItems do
  dest[ insertPos + i - 1] := src[ i - 1 ];

In this case you should consider the situation where you are adding more items than the destination list has room for. Whether this means only replacing as many items as will "fit", adding additional items to 'make room' or not assigning any at all (unless all will fit), is a question that only your requirements can answer.

However, if your intention is to INSERT the items into the destination list, then you can use a combination of InsertRange() and Copy() together with the internal array of <T> maintained by the source list. For example, using two instances of a TList<String>:

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

dest.InsertRange( insertIndex, Copy( src.List, 0, maxItems ) );

To insert the entire src list you do not need to use Copy() but can reference the source list directly in the InsertRange() method:

dest.InsertRange( insertIndex, src );

Performance Notes:

The use of Copy() is a potentially expensive operation if the source list is large and/or the number of sub-items being added is small. However, the actual insertion of the items into the destination list is very efficient as the InsertRange() method is able to make room for the new items in the destination list in a single operation and then insert the new items in the space created for them, so for larger numbers of items being added it may still prove to be the most efficient.

The alternative approach would be to iteratively insert the source items individually:

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

Whilst this avoids copying array items being inserted, inserting iteratively is itself potentially inefficient if the destination list is large and a larger number of items are being inserted, as room for each item in the destination list has to be made separately for each insert (although the potential impact of this may be significantly improved by explicitly calculating and pre-allocating the Capacity of the destination list).

e.g. if you are inserting 100 items from a 1000 item list into the (exact) middle of a 2000 item list:

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

For inserting 100 items, InsertRange() is potentially the most efficient. By contrast, if inserting only a single item from the source list then the InsertRange() approach incurs a potentially excessive overhead.

As I think should be obvious, different starting conditions would determine which of the two approaches is the most efficient, and should be considered if performance is a significant concern.




回答2:


I would use AddRange for append Items on the end or InsertRange to insert Items on a specific index.




回答3:


I'm assuming that both lists are generic TList<T>. And that you are copying over existing items rather than extending the destination.

In which case, I think a for loop with an assignment using := is the way to go. Since you are dealing with a generic list you need to use an operator that can work with any generic type T. Assuming you need to support T that is a managed type then you cannot perform a simple memory copy. That leaves you with assignment.



来源:https://stackoverflow.com/questions/26721955/delphi-tlistt-copy-into-another-tlist

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!