I’ve wrote a small array wrapper class which mimics the built-in Collection for adding and retrieving items. Once the object is created, you set the array capacity and that would not change.
'// ArrayList Class
Private arr() As String
Private position As Long
' Add
Public Sub Add(ByVal Value As String)
arr(position) = Value
position = position + 1
End Sub
' Count
Public Function Count() As Long
Count = UBound(arr)
End Function
' Item
Public Function Item(ByVal Index As Long) As String
Item = arr(Index)
End Function
' SetCapacity
Public Sub SetCapacity(ByVal arrsize As Long)
ReDim arr(arrsize)
End Sub
Testing the object:
Sub TestArrayList()
Dim a As ArrayList
Set a = New ArrayList
a.SetCapacity 4
a.Add "One"
a.Add "Two"
a.Add "Three"
a.Add "Four"
a.Add "Five"
Dim i As Long
For i = 0 To a.Count
Debug.Print a.Item(i)
Next i
End Sub
'Output as expected
'One
'Two
'Three
'Four
'Five
It is widely known that expensive operations of an array are ReDim Preserve
where a new array is created and the items of the old array are being copied.
In the object above, we only create a new array when calling the SetCapacity(arrsize)
method. No need to preserve any items. Thus the expensive operation here is the creation of the new array (fixed size) which is only performed once.
The question in terms of speed and overhead is: would a built-in collection be more appropriate than the above wrapper object?
The aim is to create a Collection of objects but I'm not sure which would be more appropriate, a Collection(Of Collection)
or a Collection(Of ArrayList)
.
In terms of data, the ArrayList will hold around 16 elements and the Collection around 1,500 objects.
1 Answer 1
I hold issue with the way you determine your wrapper's size -
Public Sub SetCapacity(ByVal arrsize As Long) ReDim arr(arrsize) End Sub
The arrsize
I pass will be 0-based, so if I want 5, I have to put 4. Not intuitive. Instead
RedDim arr(1 to arrsize)
And then there's not really any reason for this
Public Function Count() As Long Count = UBound(arr) End Function
Because your iterations would be LBound(arr) to Ubound(arr)
.
Also, I think holding the position in a class level variable is kind of sloppy. Like was mentioned in the comments, there are built-in objects that can do this for you - there's no real reason to reinvent the wheel here.
Explore related questions
See similar questions with these tags.
Scripting.Dictionary
? \$\endgroup\$Count
should equalposition - 1
. You could add agetCapacity
method that equalsarr(arrsize)
but in the VBA I would makeCapacity
a property. \$\endgroup\$