Jump to content

easy way to delete a multi-dim'ed array row


Recommended Posts

_arraydelete() is bombing when I try to delete a row in my multi-dim'ed array

for $i = $aSource[0][0] to 1 step -1
    if $aSource[$i][3]/1024/1024 < $iMin then _ArrayDelete($aSource, $i)
Next

I'm assuming then that _arraydelete() only works on single-dim'ed arrays.

If that is true, is there an easy way to delete a row out of a multi-dim'ed array?

TIA

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

... is there an easy way to delete a row out of a multi-dim'ed array?

No.

But here's the hard way:

#Include<Array.au3>

; Demo _ArrayDeleteEx() with a 5D array
Dim $avMultiD[3][4][5][6][7]
$avMultiD[1][2][2][2][2] = "Test cell stored at $avMultiD[1][2][2][2][2]"
$avMultiD[2][2][2][2][2] = "Test cell stored at $avMultiD[2][2][2][2][2]"
MsgBox(64, "Debug: Before", "$avMultiD[1][2][2][2][2] = " & $avMultiD[1][2][2][2][2])
_ArrayDeleteEx($avMultiD, 1)
MsgBox(64, "Debug: After", "$avMultiD[1][2][2][2][2] = " & $avMultiD[1][2][2][2][2])


;===============================================================================
; Function Name:    _ArrayDeleteEx()
; Description:      Deletes the specified first dimension element from the given array, 
;                       returning the adjusted array.  Extended to work with arrays with 
;                       from one to five subscripts (dimensions).
; Returns:          On success returns 1 and the ByRef array is updated.
;                   On failure returns 0, sets @error (see code below), and leaves the array unchanged.
; Author(s):        Cephas <cephas at clergy dot net>
; Modifications:    Array is passed via Byref  - Jos van der zande
;                   Multi-Dimensional arrays  - PsaltyDS
;===============================================================================
Func _ArrayDeleteEx(ByRef $avInput, $iIndex)
    Local $s, $s1, $s2, $s3, $s4, $s5, $SourceIndex
    ; Find excuses not to run...
    If Not IsArray($avInput) Then Return SetError(1, 0, 0)
    If Not IsInt($iIndex) Then Return SetError(1, 0, 0)
    If UBound($avInput) = 1 Then Return SetError(2, 0, 0)
    If $iIndex > UBound($avInput) - 1 Then Return SetError(3, 0, 0)
    
    ; Get subscripts
    Local $avSubs[UBound($avInput, 0) + 1]
    $avSubs[0] = UBound($avInput, 0)
    If $avSubs[0] > 5 Then Return SetError(4, 0, 0)
    For $s = 1 To $avSubs[0]
        $avSubs[$s] = UBound($avInput, $s)
    Next
    
    ; Create return array
    Switch $avSubs[0]
        Case 1
            Local $avRET[$avSubs[1] - 1]
        Case 2
            Local $avRET[$avSubs[1] - 1][$avSubs[2]]
        Case 3
            Local $avRET[$avSubs[1] - 1][$avSubs[2]][$avSubs[3]]
        Case 4
            Local $avRET[$avSubs[1] - 1][$avSubs[2]][$avSubs[3]][$avSubs[4]]
        Case 5
            Local $avRET[$avSubs[1] - 1][$avSubs[2]][$avSubs[3]][$avSubs[4]][$avSubs[5]]
        Case Else
            Return SetError(5, 0, 0)
    EndSwitch
    
    $SourceIndex = 0
    
    For $s1 = 0 To $avSubs[1] - 2
        If $SourceIndex = $iIndex Then $SourceIndex += 1
        If $avSubs[0] = 1 Then
            $avRET[$s1] = $avInput[$SourceIndex]
        Else
            For $s2 = 0 To $avSubs[2] - 1
                If $avSubs[0] = 2 Then
                    $avRET[$s1][$s2] = $avInput[$SourceIndex][$s2]
                Else
                    For $s3 = 0 To $avSubs[3] - 1
                        If $avSubs[0] = 3 Then
                            $avRET[$s1][$s2][$s3] = $avInput[$SourceIndex][$s2][$s3]
                        Else
                            For $s4 = 0 To $avSubs[4] - 1
                                If $avSubs[0] = 4 Then
                                    $avRET[$s1][$s2][$s3][$s4] = $avInput[$SourceIndex][$s2][$s3][$s4]
                                Else
                                    For $s5 = 0 To $avSubs[5] - 1
                                        $avRET[$s1][$s2][$s3][$s4][$s5] = $avInput[$SourceIndex][$s2][$s3][$s4][$s5]
                                    Next
                                EndIf
                            Next
                        EndIf
                    Next
                EndIf
            Next
        EndIf
        $SourceIndex += 1
    Next
    
    ; Return results
    $avInput = $avRET
    Return 1
EndFunc   ;==>_ArrayDeleteEx

:rolleyes:

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Damn....

Guess I'll just create another array and fill it while I loop through the original array then blow the original away

Oh well.

I looked over the _ArrayDelete function...all it does is create another array too,

Suggestion to AutoIT dev team: how about a true entry remove from an array....with options to renumber array and update array[0] count. Should work with all arrays, single and multi-dimed. :rolleyes:

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

  • 2 years later...

No.

But here's the hard way:

#Include<Array.au3>

; Demo _ArrayDeleteEx() with a 5D array
Dim $avMultiD[3][4][5][6][7]
$avMultiD[1][2][2][2][2] = "Test cell stored at $avMultiD[1][2][2][2][2]"
$avMultiD[2][2][2][2][2] = "Test cell stored at $avMultiD[2][2][2][2][2]"
MsgBox(64, "Debug: Before", "$avMultiD[1][2][2][2][2] = " & $avMultiD[1][2][2][2][2])
_ArrayDeleteEx($avMultiD, 1)
MsgBox(64, "Debug: After", "$avMultiD[1][2][2][2][2] = " & $avMultiD[1][2][2][2][2])


;===============================================================================
; Function Name:    _ArrayDeleteEx()
; Description:      Deletes the specified first dimension element from the given array, 
;                       returning the adjusted array.  Extended to work with arrays with 
;                       from one to five subscripts (dimensions).
; Returns:          On success returns 1 and the ByRef array is updated.
;                   On failure returns 0, sets @error (see code below), and leaves the array unchanged.
; Author(s):        Cephas <cephas at clergy dot net>
; Modifications:    Array is passed via Byref  - Jos van der zande
;                   Multi-Dimensional arrays  - PsaltyDS
;===============================================================================
Func _ArrayDeleteEx(ByRef $avInput, $iIndex)
    Local $s, $s1, $s2, $s3, $s4, $s5, $SourceIndex
    ; Find excuses not to run...
    If Not IsArray($avInput) Then Return SetError(1, 0, 0)
    If Not IsInt($iIndex) Then Return SetError(1, 0, 0)
    If UBound($avInput) = 1 Then Return SetError(2, 0, 0)
    If $iIndex > UBound($avInput) - 1 Then Return SetError(3, 0, 0)
    
    ; Get subscripts
    Local $avSubs[UBound($avInput, 0) + 1]
    $avSubs[0] = UBound($avInput, 0)
    If $avSubs[0] > 5 Then Return SetError(4, 0, 0)
    For $s = 1 To $avSubs[0]
        $avSubs[$s] = UBound($avInput, $s)
    Next
    
    ; Create return array
    Switch $avSubs[0]
        Case 1
            Local $avRET[$avSubs[1] - 1]
        Case 2
            Local $avRET[$avSubs[1] - 1][$avSubs[2]]
        Case 3
            Local $avRET[$avSubs[1] - 1][$avSubs[2]][$avSubs[3]]
        Case 4
            Local $avRET[$avSubs[1] - 1][$avSubs[2]][$avSubs[3]][$avSubs[4]]
        Case 5
            Local $avRET[$avSubs[1] - 1][$avSubs[2]][$avSubs[3]][$avSubs[4]][$avSubs[5]]
        Case Else
            Return SetError(5, 0, 0)
    EndSwitch
    
    $SourceIndex = 0
    
    For $s1 = 0 To $avSubs[1] - 2
        If $SourceIndex = $iIndex Then $SourceIndex += 1
        If $avSubs[0] = 1 Then
            $avRET[$s1] = $avInput[$SourceIndex]
        Else
            For $s2 = 0 To $avSubs[2] - 1
                If $avSubs[0] = 2 Then
                    $avRET[$s1][$s2] = $avInput[$SourceIndex][$s2]
                Else
                    For $s3 = 0 To $avSubs[3] - 1
                        If $avSubs[0] = 3 Then
                            $avRET[$s1][$s2][$s3] = $avInput[$SourceIndex][$s2][$s3]
                        Else
                            For $s4 = 0 To $avSubs[4] - 1
                                If $avSubs[0] = 4 Then
                                    $avRET[$s1][$s2][$s3][$s4] = $avInput[$SourceIndex][$s2][$s3][$s4]
                                Else
                                    For $s5 = 0 To $avSubs[5] - 1
                                        $avRET[$s1][$s2][$s3][$s4][$s5] = $avInput[$SourceIndex][$s2][$s3][$s4][$s5]
                                    Next
                                EndIf
                            Next
                        EndIf
                    Next
                EndIf
            Next
        EndIf
        $SourceIndex += 1
    Next
    
    ; Return results
    $avInput = $avRET
    Return 1
EndFunc   ;==>_ArrayDeleteEx

:idea:

Hey this is nice. Thanks for sharing.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...