Re: [RESOLVED] Delete item(s) from array
Quote:
Originally Posted by Merri
Spoo, you can still keep the logic simple, you just need to reconsider the order you do things:
Code:
kk = 0
kill = "B"
For ii = 0 to UBound(MyArray)
If MyArray(ii) <> kill Then
If kk < ii Then
MyArray(kk) = MyArray(ii)
MyArray(ii) = Empty
End If
kk = kk + 1
Else
MyArray(ii) = Empty
End If
Next ii
That's the code I was looking for in the OP. I don't see a need to zero out deleted values, though, since they'll either get overwritten or redimmed into the void.
Code:
Private Sub FilterUDT(ptyp() As TESTUDT, pstrFilter As String)
Dim lngKeep As Long
Dim lngSwap As Long
For lngSwap = 0 To UBound(ptyp)
If ptyp(lngSwap).B <> pstrFilter Then
If lngKeep < lngSwap Then ptyp(lngKeep) = ptyp(lngSwap)
lngKeep = lngKeep + 1
End If
Next
Select Case lngKeep
Case 0: Erase ptyp
Case Is <= UBound(ptyp): ReDim Preserve ptyp(lngKeep - 1)
End Select
End Sub
Re: [RESOLVED] Delete item(s) from array
Yeah, that's tight. A nice combination of simplicity and efficiency.
Re: [RESOLVED] Delete item(s) from array
There is just one problem: when you Erase an array in function, it may cause major problems in the code that assumes the array remains in place. This would force you to consider using an API to resize the array so that you can have a valid array of 0 elements instead of a null array:
Code:
Private Sub FilterUDT_tight2(ptyp() As TESTUDT, pstrFilter As String)
Dim lngKeep As Long
Dim lngSwap As Long
Dim lngReDim(0 To 1) As Long
For lngSwap = 0 To UBound(ptyp)
If ptyp(lngSwap).B <> pstrFilter Then
If lngKeep < lngSwap Then ptyp(lngKeep) = ptyp(lngSwap)
lngKeep = lngKeep + 1
End If
Next
lngReDim(0) = lngKeep
SafeArrayRedim Not Not ptyp, lngReDim(0)
Debug.Assert App.hInstance
End Sub
I included the earlier tight code into the test project.
Private Declare Function SafeArrayRedim Lib "oleaut32" (ByVal saPtr As Long, saBound As Long) As Long
Re: [RESOLVED] Delete item(s) from array
Quote:
Originally Posted by Merri
Ellis Dee: I changed the test to ReDim a long array with 65536 items to each UDT element. Now your code runs for nearly 400 ms, where in comparison mine and LaVolpe's codes remain roughly near the same speed (LaVolpe's at some 11 ms, mine at 0.5 ms). The array size grows so big that clicking the button continuously makes computer to swap though, but that would just be an extreme example.
Edit
I shrunk the size to 128 items that is already in the area of possible use, and LaVolpe's is still nearly twice faster. 128 items in Long array = 512 bytes. So if you have any related data, you will lose performance unless you only strictly move the actual array items.
I'm happy with the performance of the non-API version, especially the single loop method you posted. Seems so simple looking at it now, but I just couldn't figure it out. You rock.
I do have related data, though I'm not sure if it's how you mean. My app has three normalized tables, so I do need to do cascade deletions. I have some rather odd requirements:
1) No installation allowed, so I can't use dependencies.
2) Data file, which contains all three tables in a single file, must remain smaller than 50k unzipped.
3) Compiled exe must zip to < 50k
Due to 1) and 2) I can't use recordsets. Due to 3) I really can't use either of the faster methods since there is so much more code involved. Note that because they are udts, I need three copies of this function; one for each table. (udt array) The exe currently zips down to 38k, and I have some more stuff to add, so this most recent 15-line version is perfect. Kind of reminds me of the old C days under DOS and worrying about memory models.
Since the datasize must remain so small, the system archives any data older than 10 days. That means the 15-liner will be lightning fast for my needs.
Re: [RESOLVED] Delete item(s) from array
Quote:
Originally Posted by Merri
There is just one problem: when you Erase an array in function, it may cause major problems in the code that assumes the array remains in place. This would force you to consider using an API to resize the array so that you can have a valid array of 0 elements instead of a null array
What code would assume the array remains in place?
Re: [RESOLVED] Delete item(s) from array
If the next line outside procedure calls UBound you will get an error if the array has been Erased.
Re: [RESOLVED] Delete item(s) from array
Oh, I thought you meant "in place" as in it still resides in the same block of memory. You mean "in place" as in there is an actual array.
Yeah, I'm aware of the issues of dealing with uninitialized arrays. I maintain the UBound of the three tables in module-level "property" variables, which get set to -1 when their associated arrays are unintialized. (Though I handle the data in bas modules, the module-level variables are treated like property variables.)