Tuesday, November 18, 2008

The DynamicArray Class

The DynamicArray Class
This class needs only one member variable, the actual array that is used to store the data (named aData). In the Initialize event, aData is Redimed as an array with one element. Note that arrays are indexed starting at zero, not one, in this class.

The class contains two Property Get statements: Data and DataArray. Data returns a particular array element while DataArray returns the entire array. A single Property Let statement exists for the Data property. This array does the grunt work of Rediming the array, if needed.

The DynamicArray class contains three methods: StartIndex, StopIndex, and Delete. StartIndex simply returns the starting array index (like LBound) while StopIndex returns the array's current greatest possible index (like UBound). The third and final method, Delete, removes a particular element from the array and then compacts the array.


Class DynamicArray
'************** Properties **************
Private aData
'****************************************

'*********** Event Handlers *************
Private Sub Class_Initialize()
Redim aData(0)
End Sub
'****************************************

'************ Property Get **************
Public Property Get Data(iPos)
'Make sure the end developer is not requesting an
'"out of bounds" array element
If iPos <> UBound(aData) then
Exit Property 'Invalid range
End If

Data = aData(iPos)
End Property

Public Property Get DataArray()
DataArray = aData
End Property
'****************************************

'************ Property Let **************
Public Property Let Data(iPos, varValue)
'Make sure iPos >= LBound(aData)
If iPos < LBound(aData) Then Exit Property

If iPos > UBound(aData) then
'We need to resize the array
Redim Preserve aData(iPos)
aData(iPos) = varValue
Else
'We don't need to resize the array
aData(iPos) = varValue
End If
End Property
'****************************************


'************** Methods *****************
Public Function StartIndex()
StartIndex = LBound(aData)
End Function

Public Function StopIndex()
StopIndex = UBound(aData)
End Function

Public Sub Delete(iPos)
'Make sure iPos is within acceptable ranges
If iPos <> UBound(aData) then
Exit Sub 'Invalid range
End If

Dim iLoop
For iLoop = iPos to UBound(aData) - 1
aData(iLoop) = aData(iLoop + 1)
Next

Redim Preserve aData(UBound(aData) - 1)
End Sub
'****************************************
End Class



To use the DynamicArray class, simply create an instance of the class like so:

Dim objDynArray
Set objDynArray = New DynamicArray

To add elements to the class instance, simply use the Data property like so:

objDynArray.Data(4) = "Hello!"

To loop through the array you can use code like:

Dim i
For i = LBound(objDynArray.DataArray) to UBound(objDynArray.DataArray)
'Or, the above line could be replaced by:
'For i = objDynArray.StartIndex() to objDynArray.StopIndex()

Response.Write i & ".) " & objDynArray.Data(i) & "
"
Next

Finally, to delete an item, use the Delete method like so:

Dim objDynArray
Set objDynArray = New DynamicArray

objDynArray(0) = "Hello"
objDynArray(2) = "world!"
objDynArray(1) = "there"

'The array now has the values ("Hello", "there", "world!")
'Delete the "there" element (index = 1) so we have Hello, world!
objDynArray.Delete 1

'Now, objDynArray has the values ("Hello", "world!")

With the DynamicArray class you no longer have to worry about constantly Rediming an array or making sure that you have legal array bounds. This class allows you to just slap a value in the array position you want. If the array isn't big enough, it grows. If you want to get rid of an array element, the array compacts itself for you.

A Note on Performance
Notice that each time the developer attempts to insert an array element whose position is too big, the array issues a Redim statement. This will lead to a ton of Redim statements if the developer does something like:

Dim i
For i = 0 to SomeBigNumber
objDynArray.Data(i) = SomeValue
Next

Rather than just adding one element position when Rediming the array in the Data Let Property, why not add a number of elements? This way fewer Redim statements are issued, resulting in fewer memory allocations. Of course if you allocate too many array elements at a time, it will lead to wasted space.

I hope you found this article interesting and informative, and hopefully you will find the class applicable to your current projects! Feel free to use the DynamicArray class in any of your ASP pages!

Happy Programming!

No comments: