1
\$\begingroup\$

So I'm building a 2D Array class.

I want to have CopyArray and RemoveIndexes functions. However, in both cases, the method will be the same (iterate over the array, copy every element unless it's in an index to remove, return the result).

I have 2 public methods like so:


Public Function RemoveIndexes(ByVal targetDimension As Long, ByRef indexesToRemove As Variant) As Variant
    '/ Returns a new array object with identical contents to pArray.
    '/ Will skip over target Indexes rather than copying, effectively removing them from the result.

    Dim targetsArePresent As Boolean
    targetsArePresent = ((Not IsMissing(targetDimension)) And (Not IsMissing(indexesToRemove))) '/ Check for target dimension/indexes pair

    If Not targetsArePresent Then
        PrintErrorMessage "Both target Dimension and target Indexes must be supplies"
        Stop
    Else
        If DimensionCountOfArray(indexesToRemove) <> 1 Then '/ Check that indexesToRemove is an arrayList
            PrintErrorMessage "indexesToRemove must be an arrayList"
            Stop
        End If

        Dim LB1 As Long, UB1 As Long
        AssignArrayBounds indexesToIgnore, LB1, UB1

        Dim ix As Long
        For ix = LB1 To UB1
            CheckTargets targetDimension, indexesToIgnore(ix) '/ check that the target indexes exist
        Next ix
    End If

    RemoveIndexes = InternalCopyArray(targetDimension, indexesToRemove, targetsArePresent)

End Function

Public Function CopyArray() As Variant
    '/ Returns a new array object with identical contents to pArray.

    CopyArray = InternalCopyArray

End Function

Which both call

Private Function InternalCopyArray(Optional ByRef targetDimension As Variant, Optional ByRef indexesToIgnore As Variant, Optional ByVal targetsArePresent As Boolean) As Variant
    '/ Returns a new array object with identical contents to pArray.
    '/ If target dimension & indexes are specified, will skip over them rather than copying, effectively removing them from the result.

    Dim LB1 As Long, UB1 As Long
    Dim LB2 As Long, UB2 As Long
    Me.GetBounds LB1, UB1, LB2, UB2

    Dim newArray As Variant
    If targetsArePresent Then
        Select Case targetDimension
            Case 1
                ReDim newArray(LB1 To UB1 - DimLength(indexesToIgnore, 1), LB2 To UB2)
            Case 2
                ReDim newArray(LB1 To UB1, LB2 To UB2 - DimLength(indexesToIgnore, 1))
        End Select
    Else
        ReDim newArray(LB1 To UB1, LB2 To UB2)
    End If

    Dim i As Long, j As Long
    Dim ignoreCounter As Long
    Dim ignoreIndex As Boolean
    Dim copyElement As Variant
    For i = LB1 To UB1
        If targetDimension = 2 Then ignoreCounter = 0 '/ reset each row if tagreting columns
        For j = LB2 To UB2
            If IsObject(pArray(i, j)) Then Set copyElement = pArray(i, j) Else copyElement = pArray(i, j)

            If targetsArePresent Then

                ignoreIndex = False
                Select Case targetDimension
                    Case 1
                        ignoreIndex = Not IsNull(IndexIn1DArray(indexesToIgnore, i))
                    Case 2
                        ignoreIndex = Not IsNull(IndexIn1DArray(indexesToIgnore, j))
                End Select
                If ignoreIndex Then
                    If targetDimension = 1 Then
                        If j = LB2 Then ignoreCounter = ignoreCounter + 1 '/ only increment once per row if rows targeted
                    Else
                        ignoreCounter = ignoreCounter + 1
                    End If
                Else
                    Select Case targetDimension
                        Case 1
                            If IsObject(copyElement) Then Set newArray(i - ignoreCounter, j) = copyElement Else newArray(i - ignoreCounter, j) = copyElement
                        Case 2
                            If IsObject(copyElement) Then Set newArray(i, j - ignoreCounter) = copyElement Else newArray(i, j - ignoreCounter) = copyElement
                    End Select
                End If

            Else
                If IsObject(copyElement) Then Set newArray(i, j) = copyElement Else newArray(i, j) = copyElement
            End If
        Next j
    Next i

    CopyArray = newArray

End Function

Is this a good idea?

\$\endgroup\$
  • 1
    \$\begingroup\$ Any guidance on how many items you'll be copying and filtering out? You might get better performance with the CopyMemory API function? \$\endgroup\$ – ThunderFrame May 20 '16 at 9:31
  • \$\begingroup\$ I'm not intending to use this for arrays over, say, a max of 50,000 elements. \$\endgroup\$ – Kaz May 20 '16 at 9:43
  • \$\begingroup\$ targetdimension is optional, but doesn't have a default, and the function selects a case based on it - what happens on error? Say the boolean isn't supplied or the dimension is undefined with a TRUE? \$\endgroup\$ – Raystafarian May 20 '16 at 11:07
  • \$\begingroup\$ All the arguments are validated as soon as they enter the class, in RemoveIndexes. \$\endgroup\$ – Kaz May 20 '16 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.