1
\$\begingroup\$

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.

Raystafarian
7,2991 gold badge23 silver badges60 bronze badges
asked Oct 21, 2017 at 6:04
\$\endgroup\$
8
  • \$\begingroup\$ Why not use a Scripting.Dictionary? \$\endgroup\$ Commented Oct 21, 2017 at 23:10
  • \$\begingroup\$ @ThunderFrame Thanks but what is the benefit of using a dictionary in this case? I still need a collection (or dictionary) that holds arrays (or collections). \$\endgroup\$ Commented Oct 22, 2017 at 5:41
  • \$\begingroup\$ Can't see any advantage from using a plain array - Ok, position is automatic while Adding... \$\endgroup\$ Commented Oct 26, 2017 at 13:13
  • \$\begingroup\$ What do you mean by "In terms of data, the ArrayList will hold around 16 elements and the Collection around 1,500 objects."? Count should equal position - 1. You could add a getCapacity method that equals arr(arrsize) but in the VBA I would makeCapacity a property. \$\endgroup\$ Commented Oct 29, 2017 at 15:42
  • 1
    \$\begingroup\$ If you want to emulate your own ArrayList class for the learning experience, you might want to look at my post VBA Class to Encapsulate the System.Collections.ArrayList Class . \$\endgroup\$ Commented Oct 29, 2017 at 16:45

1 Answer 1

3
\$\begingroup\$

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.

answered Mar 21, 2018 at 2:50
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.