clsStackArray

As some of you may know, I find myself coding in Visual Basic often these past few months. Having a background of PHP and Perl, I find it frustrating that I am unable to manipulate arrays as if it were a stack, as I could in PHP via array_push() and array_pop().

So, I went out and coded my own clsStackArray class. And I found a similar class developed by Andrew McMillian. While mine is simpler, it does not allow insertion of objects (as I won’t be needing it anyway, since I mostly chuck strings and numbers in it) but if you want so, it could be altered minimally.

AsArray() is for use with For Each statements and the ever indispensable Join().

I wrote this in Access VBA, but most likely it’ll work on plain-old VB as well:

Option Base 0
Option Explicit

Private varArray() As Variant

Public Function AsArray() As Variant()
    AsArray = varArray()
End Function

Public Sub Clear()
    varArray = Array()
End Sub

' merely an alias to Size.
Public Function Count() As Long
    Count = Size()
End Function

Public Function IsEmpty() As Boolean
    IsEmpty = Not (Size() > 0)
End Function

' added to provide the same compatibility to McMillian's StackClass
' http://www.paradoxes.info/code/StackClass.html
Public Function Peek() As Variant
    Peek = varArray(UBound(varArray))
End Function

Public Function Pop()
    Dim lngSize As Long

    'resize the array
    lngSize = Size()

    ' set the return value first
    Pop = Peek()

    If (lngSize > 1) Then
        ' minus two because of the upper bound
        ReDim Preserve varArray(lngSize - 2)
    ElseIf (lngSize = 1) Then                   ' only one element
        'it seems that there's no other way...
        Clear
    End If

End Function

Public Function Push(Value As Variant)

    ' resize the array.
    ReDim Preserve varArray(Size())

    varArray(UBound(varArray)) = Value

    ' return the value just pushed in
    Push = Value
End Function

'
' returns 0 for an empty array, >=1 if it's not.
Public Function Size() As Long

    ' assume the array to be of size 0 since ubound is bound (pardon the pun) to
    ' throw an exception if the array passed is empty.
    Size = 0

    On Error Resume Next
    Size = UBound(varArray) + 1              ' add 1 to get a human-understandable size.

End Function

Here’s a sample on how to use it (and how I tested it out:)

Sub TestStackArray()
    Dim sa As New clsStackArray

    Debug.Print "isempty: " & sa.IsEmpty()

    sa.Push "0"
    Debug.Print "isempty: " & sa.IsEmpty()
    sa.Push "1"
    sa.Push "2"
    sa.Push "3"
    sa.Push "4"
    sa.Push "5"
    sa.Push "6"
    sa.Push "7"
    sa.Push "8"

    Debug.Print sa.Size & " - " & Join(sa.AsArray(), ", ")
    Debug.Print "pop: " & sa.Pop()
    Debug.Print sa.Size & " - " & Join(sa.AsArray(), ", ")

    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()
    Debug.Print "pop: " & sa.Pop()

    Debug.Print "isempty: " & sa.IsEmpty()
End Sub

It should return:

isempty: True
isempty: False
9 - 0, 1, 2, 3, 4, 5, 6, 7, 8
pop: 8
8 - 0, 1, 2, 3, 4, 5, 6, 7
pop: 7
pop: 6
pop: 5
pop: 4
pop: 3
pop: 2
pop: 1
pop: 0
isempty: True

Leave a Reply