Jump to content

Recommended Posts

Posted (edited)

My solution is to write nested arrays without copying.

The problem was described hier.

 

Function:

#include <Array.au3>

; #FUNCTION# ====================================================================================================================
; Name ..........: _ArrayNestedSet
; Description ...: Assigns a value to an element of a nested 1D array.
; Syntax ........: _ArrayNestedSet(ByRef $aArray, $vIndex, $vValue)
; Parameters ....: $aArray              - an array of arrays.
;                  $vIndex              - an index or 1d-array of indexes;
;                                         a size if $vValue not defined (zero to delete).
;                  $vValue              - a value (create, resize or delete if not defined).
;
; Return values .: on success           - 1
;                    @extended            - nesting level of operation
;                  on failure           - 0
;                    @extended            - nesting level of error
;                    @error = 1           - invalid array
;                    @error = 2           - invalid index
; Author ........:
; Modified ......: kovlad
; Remarks .......: 
; Related .......:
; Link ..........: https://www.autoitscript.com/forum/topic/185638-assign-a-value-to-an-array-in-array-element/
;                  https://www.autoitscript.com/trac/autoit/ticket/3515?replyto=description
; Example .......: Yes
; ===============================================================================================================================
Func _ArrayNestedSet(ByRef $aArray, $vIndex, $vValue = Default)

    Local $extended = @extended + 1

    If IsArray($vIndex) Then
        If UBound($vIndex, 0) <> 1 Then _
            Return SetError(2, $extended)

        If UBound($vIndex) > 1 Then
            If UBound($aArray, 0) <> 1 Then _
                Return SetError(1, $extended)

            ; keep index for this array
            Local $i = $vIndex[0]
            If $i < 0 Or UBound($aArray) <= $i Then _
                Return SetError(2, $extended)

            ; delete index of this array
            _ArrayDelete($vIndex, 0)

            ; recursive function call
            Local $return = _ArrayNestedSet($aArray[$i], $vIndex, $vValue)
            If @error Then
                Return SetError(@error, @extended + 1, 0)
            Else
                Return SetExtended(@extended + 1, 1)
            EndIf
        Else
            $vIndex = $vIndex[0]
        EndIf
    EndIf

    If $vValue = Default Then
        If $vIndex < 0 Then _
            Return SetError(2, $extended)

        If $vIndex = 0 Then

            ; delete array and free memory
            $aArray = 0
            Return SetExtended($extended, 1)
        EndIf

        If UBound($aArray, 0) = 1 Then

            ; resize array keeping data
            ReDim $aArray[$vIndex]
            Return SetExtended($extended, 1)
        Else

            ; create new nested array
            Local $aTmp[$vIndex]
            $aArray = $aTmp
            Return SetExtended($extended, 1)
        EndIf
    Else
        If UBound($aArray) <= $vIndex Then _
            Return SetError(2, $extended + 1)

        ; set value of array entry
        $aArray[$vIndex] = $vValue
        Return SetExtended($extended, 1)
    EndIf

EndFunc

 

Examples:

; write value to 1st nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write value to 1st nested array" & @CRLF)
Local $aTmp1[4] = [1,2,3,4]
_ArrayDisplay($aTmp1, "$aTmp1")
Local $aArray[2] = [$aTmp1]
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], 3, 14) = " & _ArrayNestedSet($aArray[0], 3, 14) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF & @CRLF)
_ArrayDisplay($aArray[0], "$aArray[0]")

; resize 1st nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : resize 1st nested array" & @CRLF)
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], 8) = " & _ArrayNestedSet($aArray[0], 8) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF & @CRLF)
_ArrayDisplay($aArray[0], "$aArray[0]")

; write array to 1st nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write array to 1st nested array" & @CRLF)
Local $aTmp11[4] = [11,12,13,14]
_ArrayDisplay($aTmp11, "$aTmp11")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], 2, $aTmp11) = " & _ArrayNestedSet($aArray[0], 2, $aTmp11) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF & @CRLF)
_ArrayDisplay(($aArray[0])[2], "($aArray[0])[2]")

; write value to 2nd nested array using index array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write value to 2nd nested array using index array" & @CRLF)
Local $aIndex1[2] = [2,3]
_ArrayDisplay($aIndex1, "$aIndex1")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], $aIndex1, 140) = " & _ArrayNestedSet($aArray[0], $aIndex1, 140) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF & @CRLF)
_ArrayDisplay(($aArray[0])[2], "($aArray[0])[2]")

; resize 2nd nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : resize 2nd nested array" & @CRLF)
Local $aIndex1[2] = [2,8]
_ArrayDisplay($aIndex1, "$aIndex1")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], $aIndex1) = " & _ArrayNestedSet($aArray[0], $aIndex1) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF & @CRLF)
_ArrayDisplay(($aArray[0])[2], "($aArray[0])[2]")

; create new 3rd nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : create new 3rd nested array" & @CRLF)
Local $aIndex2[3] = [2,7,6]
_ArrayDisplay($aIndex2, "$aIndex2")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], $aIndex2) = " & _ArrayNestedSet($aArray[0], $aIndex2) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF & @CRLF)
_ArrayDisplay((($aArray[0])[2])[7], ")($aArray[0])[2])[7]")

; delete 3rd nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : delete 3rd nested array" & @CRLF)
Local $aIndex3[3] = [2,7,0]
_ArrayDisplay($aIndex3, "$aIndex2")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], $aIndex3) = " & _ArrayNestedSet($aArray[0], $aIndex3) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF)
ConsoleWrite("IsArray((($aArray[0])[2])[7]) = " & IsArray((($aArray[0])[2])[7]) & @CRLF & @CRLF)

; write 0 in 1st nested array to delete the 2nd nested array
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write 0 in 1st nested array to delete the 2nd nested array" & @CRLF)
Local $aIndex4[1] = [2]
_ArrayDisplay($aIndex4, "$aIndex4")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], $aIndex4, 0) = " & _ArrayNestedSet($aArray[0], $aIndex4, 0) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF)
ConsoleWrite("IsArray(($aArray[0])[2]) = " & IsArray(($aArray[0])[2]) & @CRLF & @CRLF)

; delete 1st nested array (same as '$aArray[0] = 0')
ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : delete 1st nested array (same as '$aArray[0] = 0')" & @CRLF)
Local $aIndex5[1] = [0]
_ArrayDisplay($aIndex5, "$aIndex5")
ConsoleWrite( _
    "_ArrayNestedSet($aArray[0], $aIndex5) = " & _ArrayNestedSet($aArray[0], $aIndex5) & @CRLF & _
    "    @error    = " & @error & @CRLF & _
    "    @extended = " & @extended & @CRLF)
ConsoleWrite("IsArray($aArray[0]) = " & IsArray($aArray[0]) & @CRLF & @CRLF)

 

Edited by kovlad
Added the function description to the header.

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
×
×
  • Create New...