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.
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.
I would use AddRange for append Items on the end or InsertRange to insert Items on a specific index.
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.