Jump to content

_BetterArrayDisplay for multi-dimensional arrays


OverloadUT
 Share

Recommended Posts

I use arrays a lot.

I also use _ArrayDisplay a lot for debugging. However, I was constantly getting frustrated with the fact that it not only didn't support multi-dimensional arrays, but it didn't even have proper error handing when they are passed in!

I set out to write a better _ArrayDisplay function that could handle arrays of any dimension. Unfortunately I wasn't able to make it work with unlimited, so I coded this version that works on arrays up to 4 dimensions. There is also a _BetterArrayConsoleDump() function that does the same thing, but it dumps to the console instead of a MsgBox.

It also has the added feature of displaying nested arrays - it can do that to unlimited dimensions.

Here is some example output to the console. This is a 1 Dimensional Array with a 4 dimensional array nested in the 8th index:

1 Dimensional Array
[0]  = 17
[1]  = 54
[2]  = 3
[3]  = 77
[4]  = 53
[5]  = 87
[6]  = 52
[7]  = 4 Dimensional Array
        [0]
         |--[0]
         |---+--[0]
         |---+---+--[0]  = 71
         |---+--[1]
         |---+---+--[0]  = 28
         |--[1]
         |---+--[0]
         |---+---+--[0]  = 85
         |---+--[1]
         |---+---+--[0]  = 82
        [1]
         |--[0]
         |---+--[0]
         |---+---+--[0]  = 91
         |---+--[1]
         |---+---+--[0]  = 73
         |--[1]
         |---+--[0]
         |---+---+--[0]  = 84
         |---+--[1]
         |---+---+--[0]  = 3
        [2]
         |--[0]
         |---+--[0]
         |---+---+--[0]  = 17
         |---+--[1]
         |---+---+--[0]  = 20
         |--[1]
         |---+--[0]
         |---+---+--[0]  = 4
         |---+--[1]
         |---+---+--[0]  = 57
[8]  = 54
[9]  = 1

Here are the UDF's:

;===============================================================================
;
; Function Name:  _BetterArrayDisplay()
; Description:    Displays an array of any dimensions in a message box.
; Author(s):      Greg Laabs <gl-autoit at apartment167 dot com>
;
;===============================================================================
Func _BetterArrayDisplay(Const ByRef $avArray, $sTitle = "Array")
    Local $iCounter = 0, $sMsg = ""
    
    If (Not IsArray($avArray)) Then
        SetError(1)
        Return 0
    EndIf
    
    $sMsg = _BetterArrayDisplayFormat(0, $avArray)
    
    MsgBox(4096, $sTitle, $sMsg)
    SetError(0)
    Return 1
EndFunc   ;==>_BetterArrayDisplay

;===============================================================================
;
; Function Name:  _BetterArrayConsoleDump()
; Description:    Displays an array of any dimensions in the console.
; Author(s):      Greg Laabs <gl-autoit at apartment167 dot com>
;
;===============================================================================
Func _BetterArrayConsoleDump(Const ByRef $avArray, $sTitle = "Array Dump")
    Local $iCounter = 0, $sMsg = ""
    
    If (Not IsArray($avArray)) Then
        SetError(1)
        Return 0
    EndIf
    
    $sMsg = _BetterArrayDisplayFormat(0, $avArray)
    
    ConsoleWrite($sTitle & @CRLF)
    ConsoleWrite($sMsg)
    SetError(0)
    Return 1
EndFunc   ;==>_BetterArrayConsoleDump

;===============================================================================
;
; Function Name:  _BetterArrayDisplayFormat()
; Description:    Formats the string displayed in _BetterArrayConsoleDump and
;                 _BetterArrayDisplay()
; Author(s):      Greg Laabs <gl-autoit at apartment167 dot com>
;
;===============================================================================
Func _BetterArrayDisplayFormat($deep, Const ByRef $avArray)
    Local $iCounter = 0, $jCounter = 0, $kCounter, $lCounter, $sCounter
    Local $sMsg = ""
    
    $sMsg &= UBound($avArray, 0) & " Dimensional Array" & @CRLF
    
    If UBound($avArray, 0) > 1 Then
        ;FIRST DIMENSION (I) RECURSIVE
        For $iCounter = 0 To UBound($avArray) - 1
            For $sCounter = 1 To $deep
                If $sCounter = $deep + 1 Then
                    $sMsg &= " |--"
                ElseIf $sCounter > $deep + 1 Then
                    $sMsg &= "-+--"
                Else
                    $sMsg &= "    "
                EndIf
            Next
            $sMsg &= "[" & $iCounter & "]" & @CR
            If UBound($avArray, 0) > 2 Then
                ; SECOND DIMENSION (J) RECURSIVE
                For $jCounter = 0 To UBound($avArray, 2) - 1
                    For $sCounter = 1 To $deep + 1
                        If $sCounter = $deep + 1 Then
                            $sMsg &= " |--"
                        ElseIf $sCounter > $deep + 1 Then
                            $sMsg &= "-+--"
                        Else
                            $sMsg &= "    "
                        EndIf
                    Next
                    $sMsg &= "[" & $jCounter & "]" & @CR
                    If UBound($avArray, 0) > 3 Then
                        ; THIRD DIMENSION (K) RECURSIVE
                        For $kCounter = 0 To UBound($avArray, 2) - 1
                            For $sCounter = 1 To $deep + 2
                                If $sCounter = $deep + 1 Then
                                    $sMsg &= " |--"
                                ElseIf $sCounter > $deep + 1 Then
                                    $sMsg &= "-+--"
                                Else
                                    $sMsg &= "    "
                                EndIf
                            Next
                            $sMsg &= "[" & $kCounter & "]" & @CR
                            If UBound($avArray, 0) > 4 Then
                                ; FOURTH DIMENSION (L) RECURSIVE
                                SetError(1)
                                Return "Cannot display arrays deeper than 3 dimensions"
                            Else
                                ; FOURTH DIMENSION (L) DISPLAY
                                For $lCounter = 0 To UBound($avArray, 4) - 1
                                    For $sCounter = 1 To $deep + 3
                                        If $sCounter = $deep + 1 Then
                                            $sMsg &= " |--"
                                        ElseIf $sCounter > $deep + 1 Then
                                            $sMsg &= "-+--"
                                        Else
                                            $sMsg &= "    "
                                        EndIf
                                    Next
                                    $sMsg &= "[" & $lCounter & "]  = "
                                    If IsArray($avArray[$iCounter][$jCounter][$kCounter][$lCounter]) Then
                                        $sMsg &= _BetterArrayDisplayFormat($deep + 5, $avArray[$iCounter][$jCounter][$kCounter][$lCounter])
                                    Else
                                        $sMsg &= $avArray[$iCounter][$jCounter][$kCounter][$lCounter] & @CR
                                    EndIf
                                Next
                            EndIf
                        Next
                    Else
                        ; THIRD DIMENSION (K) DISPLAY
                        For $kCounter = 0 To UBound($avArray, 3) - 1
                            For $sCounter = 1 To $deep + 2
                                If $sCounter = $deep + 1 Then
                                    $sMsg &= " |--"
                                ElseIf $sCounter > $deep + 1 Then
                                    $sMsg &= "-+--"
                                Else
                                    $sMsg &= "    "
                                EndIf
                            Next
                            $sMsg &= "[" & $kCounter & "]  = "
                            If IsArray($avArray[$iCounter][$jCounter][$kCounter]) Then
                                $sMsg &= _BetterArrayDisplayFormat($deep + 4, $avArray[$iCounter][$jCounter][$kCounter])
                            Else
                                $sMsg &= $avArray[$iCounter][$jCounter][$kCounter] & @CR
                            EndIf
                        Next
                    EndIf
                Next
            Else
                ; SECOND DIMENSION (J) DISPLAY
                For $jCounter = 0 To UBound($avArray, 2) - 1
                    For $sCounter = 1 To $deep + 1
                        If $sCounter = $deep + 1 Then
                            $sMsg &= " |--"
                        ElseIf $sCounter > $deep + 1 Then
                            $sMsg &= "-+--"
                        Else
                            $sMsg &= "    "
                        EndIf
                    Next
                    $sMsg &= "[" & $jCounter & "]  = "
                    If IsArray($avArray[$iCounter][$jCounter]) Then
                        $sMsg &= _BetterArrayDisplayFormat($deep + 3, $avArray[$iCounter][$jCounter])
                    Else
                        $sMsg &= $avArray[$iCounter][$jCounter] & @CR
                    EndIf
                Next
            EndIf
        Next
    Else
        ; FIRST DIMENSION (I) DISPLAY
        For $iCounter = 0 To UBound($avArray) - 1
            For $sCounter = 1 To $deep
                If $sCounter = $deep + 1 Then
                    $sMsg &= " |--"
                ElseIf $sCounter > $deep + 1 Then
                    $sMsg &= "-+--"
                Else
                    $sMsg &= "    "
                EndIf
            Next
            $sMsg &= "[" & $iCounter & "]  = "
            If IsArray($avArray[$iCounter]) Then
                $sMsg &= _BetterArrayDisplayFormat($deep + 2, $avArray[$iCounter])
            Else
                $sMsg &= $avArray[$iCounter] & @CR
            EndIf
        Next
    EndIf
    Return $sMsg
EndFunc   ;==>_BetterArrayDisplayFormatoÝ÷ ض¬¶¡z·¢±©ÞÅ©©ë®*m¶ek&«¢éÝÂ+aÖ®¶­sb6æ6ÇVFRfÇC´&WGFW$'&æS2fwC° ¤FÒb33c´&t'&³5Õ³%Õ³UճР¤f÷"b33c¶ÓFò  f÷"b33c¶£ÓFò f÷"b33c¶³ÓFò@ f÷"b33c¶ÃÓFò b33c´&t'&²b33c¶Õ²b33c¶¥Õ²b33c¶µÕ²b33c¶ÅÒÒ&æFöÒÃà æW@ æW@ æW@¤æW@ ¥ô&WGFW$'&F7Æb33c´&t'&ÂgV÷C´&r'&×6t&÷gV÷C²¥ô&WGFW$'&6öç6öÆTGV×b33c´&t'&ÂgV÷C´&r'&6öç6öÆRGV×gV÷C² ¤FÒb33cµ6ÖÆÄ'&³Ð ¤f÷"b33c¶ÓFò b33cµ6ÖÆÄ'&²b33c¶ÒÒ&æFöÒÃäæW@¢b33cµ6ÖÆÄ'&³uÒÒb33c´&t'& ¥ô&WGFW$'&F7Æb33cµ6ÖÆÄ'&ÂgV÷Cµ6ÖÆÂ'&×6t&÷gV÷C²¥ô&WGFW$'&6öç6öÆTGV×b33cµ6ÖÆÄ'&ÂgV÷Cµ6ÖÆÂ'&6öç6öÆRGV×gV÷C²

Please let me know what you think of my first contribution to the AutoIt community! :D

Edited by OverloadUT
Link to comment
Share on other sites

Have you seen _ArrayBox ?

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
Link to comment
Share on other sites

Ah. For some reason when I searched for it I got no matches. I probably searched in the wrong forum by mistake.

Regardless, that is a pretty nice function, but I feel that my functions still provide very useful functionality that is missing from _ArrayBox. Namely, my functions will display nested arrays to an unlimited depth, and support arrays up to 4 dimensions (Although I don't think I've ever used arrays larger than 3 dimensions!)

Also, I don't like that _ArrayBox requires so many parameters. I only use these functions for debugging and usually just want to very quickly insert _BetterArrayDisplay($array) without having to worry about any other arguments.

But thanks for the link!

Edited by OverloadUT
Link to comment
Share on other sites

I've made this function support any number of dimensions...I made it right after I read your post about your functions only being able to support arrays with less or equal than 4 dimensions..Try this example out, and see if it works for you..

Func Imply($a,$b)
Return Not(($a) And (Not $b))
EndFunc
Func ForArray($array,$nnul=0,$cdim=1,$str="$array")
if (IsDeclared("__ForArrayReturn")=0) then Assign("__ForArrayReturn","",2)
for $i=0 to UBound($array,$cdim)-1
if $cdim<UBound($array,0) then 
ForArray($array,$nnul,$cdim+1,$str&"["&$i&"]")
else
$r=Execute($str&"["&$i&"]")
if Imply($nnul,StringLen($r)>0) then $__ForArrayReturn&=$str&"["&$i&"]="&$r&@CRLF
endif
next
Return $__ForArrayReturn
EndFunc
Dim $arr[5][6][7][8][9][10]
$arr[0][0][0][0][0][0]="51"
$arr[0][2][1][3][5][1]="11"
$h=FileOpen("result.txt",2)
FileWrite($h,ForArray($arr))
FileClose($h)

EDIT: By supplying a non-0 $nnul parameter, you are instructing the routine to ignore empty strings (possibly unassigned values) in the array..

EDIT: I notice it's taking an insane amount of time for 6-element arrays..That is most probably because of the naive recursive implementation I applied..This was just a way that popped up in about 3 minutes after I started thinking about that..Other than that, a sure way of solving the problem would be a backtracking implementation, which I will do if I get around it..

Edited by VicTT
Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Icekirby1: That's exactly how I was going to do it, and it's how my current version works with nested arrays.

The problem I ran in to was I couldn't figure out any way to get the value from an array where I didn't know the non-variable number of dimensions. Evay() doesn't work with arrays, so I figured it wasn't possible.

However, I see that VicTT's version uses Execute() to do what I wanted to do.

Had I known that worked, it would have saved me a LOT of headache!

Link to comment
Share on other sites

Regardless, that is a pretty nice function, but I feel that my functions still provide very useful functionality that is missing from _ArrayBox. Namely, my functions will display nested arrays to an unlimited depth, and support arrays up to 4 dimensions (Although I don't think I've ever used arrays larger than 3 dimensions!)

Also, I don't like that _ArrayBox requires so many parameters. I only use these functions for debugging and usually just want to very quickly insert _BetterArrayDisplay($array) without having to worry about any other arguments.

But thanks for the link!

_ArrayBox only requires one parameter, the array name. The rest are optional (and more optional parameters the better, I say). What I mainly like about it is the listbox/gui viewing of the array, I feel it is better than a msgbox. Perhaps you could expand the functionality of _ArrayBox or incorporate a gui into yours? I think you could possibly make the definitive Array Display function if you did so! :D

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
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...