Jump to content

How do I implement a dynamic 2d array?


IAMK
 Share

Recommended Posts

I've used _ArrayAdd() before for 1d arrays, but now I'm trying to use it for a 2d array, but it fails because element 0 is a 1d array?

#include <Array.au3>

Local $stepMessage[1] = ["NULL"] ;This will become a dynamically filled array.
Local $maxSteps = 1 ;Make this 2 if "Next Step" is required.
Local $step = 1 ;This will be incremented when a step is passed or failed.

Local $function[1] ;This will be a dynamically filled 2d array [$step, $functionName].
Local $functionCount = 1 ;How many automated function calls will be done. ;Default = 1 (because $function already has 1 element
Local $functionsCalled = 1 ;How many functions have been called (used for tracking what the next function is). ;Default = 1 (because $function already has 1 element

writeStep("a", '"Hello" & @CRLF & "There!"')
writeStep("m", '"Hello I AM BOB"', "tempTest()")
writeStep("ma", '"Hello" & @CRLF & @CRLF & "K"')
writeStep("x", '"This is unspecified..."', "tempTest()")

Func writeStep($executionType, $message, $functionName = "NULL")
   _ArrayAdd($stepMessage, getExecutionType($executionType) & '& "Step: " & $step & "/" & ($maxSteps - 1) & @CRLF & @CRLF & $message')

   If($functionName <> "NULL") Then ;If a function name has been provided to be run.
      Local $tempArray[2] = [$maxSteps, $functionName]

      _ArrayAdd($function, $tempArray, 0, "|", @CRLF, 1) ;Add the function to the array with the step it needs to be executed on.
   EndIf

   $maxSteps = $maxSteps + 1
EndFunc

Func getExecutionType($executionType)
   If($executionType = "m") Then
      Return '"<Manual>" & @TAB & @TAB '
   ElseIf($executionType = "a") Then
      $functionCount = $functionCount + 1

      Return '"<Auto>" & @TAB & @TAB & @TAB '
   ElseIf($executionType = "ma") Then
      $functionCount = $functionCount + 1

      Return '"<Manual/Auto>" & @TAB '
   Else
      Return '"<Unspecified>" & @TAB '
   EndIf
EndFunc

Func tempTest()
   MsgBox(0, "TEST", "I AM tempTest()")
EndFunc

While($step < $maxSteps)
MsgBox(0, "TEST", "HELLO1")
   If($functionCount > 1) Then ;Error will be thrown if no functions were added, hence this If was added.
MsgBox(0, "TEST", "HELLO2")
      If($step = $function[$functionsCalled][0]) Then
MsgBox(0, "TEST", "HELLO3")
         Execute($function[$step][1])
MsgBox(0, "TEST", "HELLO4")

         $functionsCalled = $functionsCalled + 1
      EndIf
   EndIf
MsgBox(0, "TEST", "HELLO5")

   $step = $step + 1
WEnd

There is no issue if I remove the [0] in If($step = $function[$functionsCalled][0]) Then, but of course it won't do what I want.

I've use _ArrayDisplay() and many other debugging things, and it seems like my arrays are correct, it's just that I can't use [0] because the entire array isn't 2d.
It's a 1d array with an array inside elements 1+.

Does anyone know the solution to this?

Thank you in advance.

Link to comment
Share on other sites

Do you know how many columns you require?  For example if you need 2 columns than $function[0][2], four $function[0][4] etc..., if you need to do it dynamically you would need to use _ArrayColInsert or Re-Dim.  When adding data you just use something like _ArrayAdd($function, "Column0|Column1|...") but your array needs to be able to fit that data.  Hope that makes sense.

Link to comment
Share on other sites

 My array will be like this:
$array[0]
$array[1][2]
$array[2][2]
...
$array[n][2]

You will notice inside writeStep() I have the following:

Local $tempArray[2] = [$maxSteps, $functionName]

 _ArrayAdd($function, $tempArray, 0, "|", @CRLF, 1) ;Add the function to the array with the step it needs to be executed on.

I used all the default parameters until I reached the last one so that I could force it to add an array of 2 elements into the element, rather than adding 2 elements.

When I use the following to debug, all the information shown is correct:

_ArrayDisplay($function[1])
_ArrayDisplay($function[2])

 

Link to comment
Share on other sites

But that is not a 2d array, its an array within an array, why don't you use a 2d array like example below you can then just use a For loop with ubound for the steps

#include <Array.au3>

;~ $aFunctions[n][0] = Execution Type
;~ $aFunctions[n][1] = Message
;~ $aFunctions[n][3] = Function Name
Global $aFunctions[0][3]
_AddSteps("a", '"Hello" & @CRLF & "There!"')
_AddSteps("m", '"Hello I AM BOB"', "_TempTest()")
_AddSteps("ma", '"Hello" & @CRLF & @CRLF & "K"')
_AddSteps("x", '"This is unspecified..."', "_TempTest()")
_ArrayDisplay($aFunctions)

For $i = 0 To UBound($aFunctions) - 1
    MsgBox(4096, "Test", "Execution Type: " & Execute($aFunctions[$i][0]) & @CRLF & Execute($aFunctions[$i][1]))
    If $aFunctions[$i][2] <> "" Then Execute($aFunctions[$i][2])
Next

Func _TempTest()
   MsgBox(0, "TEST", "I AM _TempTest()")
EndFunc

Func _AddSteps($sExecutionType, $sMessage, $sFunctionName = "")
    _ArrayAdd($aFunctions, _GetExecutionType($sExecutionType) & "|" & $sMessage & "|" & $sFunctionName)
EndFunc

Func _GetExecutionType(ByRef $sExecutionType)
    Switch $sExecutionType
        Case "m"
            Return '"<Manual>" & @TAB & @TAB '
        Case "a"
            Return '"<Auto>" & @TAB & @TAB & @TAB '
        Case "ma"
            Return '"<Manual/Auto>" & @TAB '
        Case Else
            Return '"<Unspecified>" & @TAB '
   EndSwitch
EndFunc

 

Link to comment
Share on other sites

@Subz I feel stupid. I don't know why I tried separating the functions into another array.
Thank you.

However, do you have an explanation on why the previous code didn't work? I'm still confused as it seems logically correct to me.

Link to comment
Share on other sites

Hi IAMK,
I just had a quick look at your script : you got errors because your 2D Array can't be declared like this, in fact you declared a 1D array :

Local $function[1] ;This will be a dynamically filled 2d array [$step, $functionName]

If you want an empty 2D array, with 2 columns, then you need to declare it like this :

Local $function[0][2] ; 0 row, 2 columns

Or if you don't feel comfortable with the "0 row", like that :

Local $function[1][2] ; 1 row, 2 columns => [[$step], [$functionName]]

Then later, when you populate it, you can do it in a simple way :

; Instead of :
; Local $tempArray[2] = [$maxSteps, $functionName]
; _ArrayAdd($function, $tempArray, 0, "|", @CRLF, 1) ;Add the function to the array with the step it needs to be executed on.

; Try :
_ArrayAdd($function, $maxSteps & "|" & $functionName)

Also it's a good idea to place an _ArrayDisplay after each _ArrayAdd during the development phase : it shows you immediately if something is going wrong :)

Good luck

 

Edited by pixelsearch
Link to comment
Share on other sites

Thats one of the issues you will get when using array within an array you would need to first use a variable to create a sub-array, you will also note that your $maxSteps is out of bounds.  Personally I would use 2d method like my example above otherwise it becomes difficult to follow when you writing it into 1d Array.

#include <Array.au3>

Local $stepMessage[1] = ["NULL"] ;This will become a dynamically filled array.
Local $maxSteps = 1 ;Make this 2 if "Next Step" is required.
Local $step = 1 ;This will be incremented when a step is passed or failed.

Local $function[1] ;This will be a dynamically filled 2d array [$step, $functionName].
Local $functionCount = 1 ;How many automated function calls will be done. ;Default = 1 (because $function already has 1 element
Local $functionsCalled = 1 ;How many functions have been called (used for tracking what the next function is). ;Default = 1 (because $function already has 1 element

writeStep("a", '"Hello" & @CRLF & "There!"')
writeStep("m", '"Hello I AM BOB"', "tempTest()")
writeStep("ma", '"Hello" & @CRLF & @CRLF & "K"')
writeStep("x", '"This is unspecified..."', "tempTest()")

Func writeStep($executionType, $message, $functionName = "NULL")
    _ArrayAdd($stepMessage, getExecutionType($executionType) & '& "Step: " & $step & "/" & ($maxSteps - 1) & @CRLF & @CRLF & $message')

    If($functionName <> "NULL") Then ;If a function name has been provided to be run.
        Local $tempArray[2] = [$maxSteps, $functionName]
        _ArrayAdd($function, $tempArray, 0, "|", @CRLF, 1) ;Add the function to the array with the step it needs to be executed on.
        $maxSteps += 1
   EndIf
EndFunc

Func getExecutionType($executionType)
   If($executionType = "m") Then
      Return '"<Manual>" & @TAB & @TAB '
   ElseIf($executionType = "a") Then
      $functionCount = $functionCount + 1
      Return '"<Auto>" & @TAB & @TAB & @TAB '
   ElseIf($executionType = "ma") Then
      $functionCount = $functionCount + 1
      Return '"<Manual/Auto>" & @TAB '
   Else
      Return '"<Unspecified>" & @TAB '
   EndIf
EndFunc

Func tempTest()
   MsgBox(0, "TEST", "I AM tempTest()")
EndFunc

MsgBox(4096, "Array Info", "$function count = " & UBound($function) & @CRLF & "$maxSteps = " & $maxSteps)
While($step < $maxSteps)
    MsgBox(0, "TEST", "HELLO1")
   If($functionCount > 1) Then ;Error will be thrown if no functions were added, hence this If was added.
        MsgBox(0, "TEST", "HELLO2")
        If IsArray($function[$step]) Then
            $aSubArray = $function[$step]
            _ArrayDisplay($aSubArray)
            If($step = $aSubArray[0]) Then
                MsgBox(0, "TEST", "HELLO3")
                Execute($aSubArray[1])
                MsgBox(0, "TEST", "HELLO4")
                $functionsCalled = $functionsCalled + 1
            EndIf
        EndIf
    EndIf
    MsgBox(0, "TEST", "HELLO5")
   $step += 1
WEnd

 

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...