|
|
Title | Remove an item from the middle of an array quickly |
Keywords | array, remove, delete, CopyMemory, MemCopy, RtlMoveMemory |
Categories | Tips and Tricks |
|
|
This example demonstrates two techniques. First, the RemoveArrayElement_Old subroutine copies items one at a time to shift them over the hole in the array. In the second method, the RemoveArrayElement_Str subroutine uses the CopyMemory API function to shift items over to fill in the hole. This method is much faster, depending on the type and size of the array.
Thanks to Josh Einstein.
|
|
Public Sub RemoveArrayElement_Old(AryVar() As String, ByVal _
RemoveWhich As Long)
'// Removes arrays the old way
Dim strTempArray() As String
Dim i As Long
Dim lngDestIndex As Long
If UBound(AryVar) - LBound(AryVar) = 0 Then
Erase AryVar
Else
ReDim strTempArray(LBound(AryVar) To _
(UBound(AryVar) - 1))
lngDestIndex = LBound(AryVar)
For i = LBound(AryVar) To UBound(AryVar)
If i <> RemoveWhich Then
strTempArray(lngDestIndex) = AryVar(i)
lngDestIndex = lngDestIndex + 1
End If
Next
AryVar = strTempArray
End If
End Sub
Public Sub RemoveArrayElement_Str(AryVar() As String, ByVal _
RemoveWhich As Long)
'// The size of the array elements
'// In the case of string arrays, they are
'// simply 32 bit pointers to BSTR's.
Dim byteLen As Byte
'// String pointers are 4 bytes
byteLen = 4
'// The copymemory operation is not necessary unless
'// we are working with an array element that is not
'// at the end of the array
If RemoveWhich < UBound(AryVar) Then
'// Copy the block of string pointers starting at
' the position after the
'// removed item back one spot.
CopyMemory ByVal VarPtr(AryVar(RemoveWhich)), ByVal _
VarPtr(AryVar(RemoveWhich + 1)), (byteLen) * _
(UBound(AryVar) - RemoveWhich)
End If
'// If we are removing the last array element
'// just deinitialize the array
'// otherwise chop the array down by one.
If UBound(AryVar) = LBound(AryVar) Then
Erase AryVar
Else
ReDim Preserve AryVar(UBound(AryVar) - 1)
End If
End Sub
|
|
|
|
|
|