SharpDressedMan Posted November 19, 2018 Posted November 19, 2018 I have an array of subarrays, eg: local $a[3] = [ 1, 2, 3 ] local $b[3] = [ 4, 5, 6 ] local $c[2] = [ $a, $b ] I can read read a subarray element of the array, as follows: local $c12 = ($c[1])[2] ; result: $c12 = 6 However, when I try to set a subarray element as follows, it fails: ($c[1])[2] = 12 ; this fails to set subarray element local $c12 = ($c[1])[2] ; result: $c12 = 6 How to set a subarray element ? Thanks
water Posted November 19, 2018 Posted November 19, 2018 You are absolutely sure you need subarrays? If yes, I think you need to extract $b to a temp array, modify the value and then update $c[1] with $b. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
Malkey Posted November 20, 2018 Posted November 20, 2018 Here are some examples of dealing with elements of a sub-array which is an element in an array. #include <Array.au3> ; --------- Testing 1D array ---------- Local $b[] = [2, 3, 4], $a[4] = [1, $b, 5, 6] _ArrayDisplay($a, "$a[4] = [1,$b,5,6]") ConsoleWrite("($a[1])[1] = " & ($a[1])[1] & @CRLF) _ASA($a[1], 1, 7) ConsoleWrite("($a[1])[1] = " & ($a[1])[1] & @CRLF) _ArrayDisplay($a[1], "3 to 7") ; --------- Testing 2D array ---------- Local $b[] = [2, 3, 4], $a[2][4] = [[1, $b, 5, 6], [9, 10, 1, 12]] _ArrayDisplay($a) ConsoleWrite("($a[0][1])[2] = " & ($a[0][1])[2] & @CRLF) ; = 4 ; ($a[0][1])[2] = 7 ; <- this does not work, produces " : error: Statement cannot be just an expression." _ASA($a[0][1], 2, 7) ; In the 2D array of $a item $a[0][1] contains a 1D arr. _ASA() function is used to put the value 7 into ($a[0][1])[2] ConsoleWrite("($a[0][1])[2] = " & ($a[0][1])[2] & @CRLF) ; now = 7 _ArrayDisplay($a[0][1], "4 to 7") ;Assign to Sub-Array (ASA) Func _ASA(ByRef $array, $iIndex, $Value) Local $aTemp = $array ; Copy the array that is stored in an array's element to $aTemp (an array). $aTemp[$iIndex] = $Value ; Assign the new value. $array = $aTemp ; Copy the modified Sub-array back to the element of the main array. EndFunc ;==>_ASA pixelsearch 1
pixelsearch Posted November 20, 2018 Posted November 20, 2018 Hello guys That's an interesting subject, thanks for your preceding comments. If I understand well, neither Water nor Malkey modify SharpDressedMan's original $b array, right ? At 1st, I thought Water was modifying it, as he refers to $b twice in his comment, ending with "then update $c[1] with $b", which applied to SharpDressedMan's script, could be interpreted like this : #include <Array.au3> local $a[3] = [ 1, 2, 3 ] local $b[3] = [ 4, 5, 6 ] local $c[2] = [ $a, $b ] local $c12 = ($c[1])[2] MsgBox(0 ,"Initial $c12" ,$c12) ; 6 ;........................... $b[2] = 12 local $c[2] = [ $a, $b ] _ArrayDisplay($b, "$b changed (6 to 12)") ;............................... _ArrayDisplay($c[1], "$c[1] changed (6 to 12)") local $c12 = ($c[1])[2] MsgBox(0 ,"Final $c12" ,$c12) ; 12 When Malkey's way keeps the original $b untouched : #include <Array.au3> local $a[3] = [ 1, 2, 3 ] local $b[3] = [ 4, 5, 6 ] local $c[2] = [ $a, $b ] local $c12 = ($c[1])[2] MsgBox(0 ,"Initial $c12" ,$c12) ; 6 ;........................... local $aTemp = $c[1] $aTemp[2] = 12 $c[1] = $aTemp _ArrayDisplay($b, "$b unchanged") ; 6 ;............................... _ArrayDisplay($c[1], "$c[1] changed (6 to 12)") local $c12 = ($c[1])[2] MsgBox(0 ,"Final $c12" ,$c12) ; 12 Both scripts give same result (12), but after re-reading Water's comment, I don't think at all he wanted to modify the original $b Array, as he also wrote : "extract $b to a temp array" which refers clearly to the b$ "included" in $c and not to the original $b as defined by local $b[] = ... Also, what's really interesting in this thread is that it clarifies a point : is array $b included in array $c static ? Or is there a dynamic link between array $c and the original $b array ? It's static, because as soon as this statement appears... local $c[2] = [ $a, $b ] ...then a copy of $b is immediately included into $c, there is absolutely no dynamic link between $c and $b (that would have been interesting if we had a choice to create a dynamic link between both arrays, modifying an element in $b, like in the 1st script above, without having to redefine again local $c[2] = [ $a, $b ]) Before working on this thread and testing examples, as I never used "arrays within arrays", I didn't know if there was a dynamic link between arrays $c and $b (or between $c and $a), now i know And to make sure, you can delete both original arrays a$ and b$, noticing that c$ is still populated : static ! #include <Array.au3> local $a[3] = [ 1, 2, 3 ] local $b[3] = [ 4, 5, 6 ] local $c[2] = [ $a, $b ] $a = 0 ; erase array $a $b = 0 ; erase array $b _ArrayDisplay($a) ; line won't execute as array $a has been erased _ArrayDisplay($b) ; line won't execute as array $b has been erased _ArrayDisplay($c, "Magic, $c still here !") _ArrayDisplay($c[0], "$c[0] i'm here too !") ; display 1,2,3 _ArrayDisplay($c[1], "$c[1] alive & kicking !") ; display 4,5,6 "I think you are searching a bug where there is no bug... don't listen to bad advice."
pixelsearch Posted November 20, 2018 Posted November 20, 2018 @Malkey : based on your examples, I found a way to simplify the _ASA function to 1 line only. That was a great experimenting day #include <Array.au3> ; --------- Testing 1D array ---------- Local $b[] = [2, 3, 4], $a[4] = [1, $b, 5, 6] _ArrayDisplay($a, "$a[4] = [1,$b,5,6]") ConsoleWrite("($a[1])[1] = " & ($a[1])[1] & @CRLF) _ASA($a[1], 1, 7) ConsoleWrite("($a[1])[1] = " & ($a[1])[1] & @CRLF) _ArrayDisplay($a[1], "3 to 7") ; --------- Assign to Sub-Array (ASA) --------- Func _ASA(ByRef $array, $iIndex, $Value) $array[$iIndex] = $Value ; Assign the new value. EndFunc ;==>_ASA "I think you are searching a bug where there is no bug... don't listen to bad advice."
Malkey Posted November 21, 2018 Posted November 21, 2018 @pixelsearch Your _ASA function to one line, that's nice - well done.
SharpDressedMan Posted November 21, 2018 Author Posted November 21, 2018 11 hours ago, pixelsearch said: @Malkey : based on your examples, I found a way to simplify the _ASA function to 1 line only. That was a great experimenting day #include <Array.au3> ; --------- Testing 1D array ---------- Local $b[] = [2, 3, 4], $a[4] = [1, $b, 5, 6] _ArrayDisplay($a, "$a[4] = [1,$b,5,6]") ConsoleWrite("($a[1])[1] = " & ($a[1])[1] & @CRLF) _ASA($a[1], 1, 7) ConsoleWrite("($a[1])[1] = " & ($a[1])[1] & @CRLF) _ArrayDisplay($a[1], "3 to 7") ; --------- Assign to Sub-Array (ASA) --------- Func _ASA(ByRef $array, $iIndex, $Value) $array[$iIndex] = $Value ; Assign the new value. EndFunc ;==>_ASA Thanks pixelsearch, This solution is the one I actually did implement to solve my problem. I was though in the hope of a builtin way to do it, without the need of a function. My problem is that I actually manage arrays of arrays of arrays of arrays... so I need to implement several _ASA variants, such as: Func _ASA(ByRef $array, $i, $Value) $array[$i] = $Value ; Assign the new value. EndFunc Func _ASA2(ByRef $array, $i, $j, $Value) _ASA($array[$i], $j, $Value) ; perform: ($array[$i])[$j] = $Value EndFunc Func _ASA3(ByRef $array, $i, $j, $k, $Value) _ASA2($array[$i], $j, $k, $Value) ; perform: (($array[$i])[$j])[$k] = $Value EndFunc ; and so on... Which is quite annoying... Anyway thanks for your answers, all.
water Posted November 21, 2018 Posted November 21, 2018 2 hours ago, SharpDressedMan said: My problem is that I actually manage arrays of arrays of arrays of arrays I think now is the perfect time to rethink your data design. Maybe multiple arrays, maybe a database ...... would avoid complex scripting and hence reduce the risk of hard to diagnose errors. Just my 2 cents worth user4157124 1 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
SharpDressedMan Posted December 10, 2018 Author Posted December 10, 2018 On 21/11/2018 at 1:10 PM, water said: I think now is the perfect time to rethink your data design. Maybe multiple arrays, maybe a database ...... would avoid complex scripting and hence reduce the risk of hard to diagnose errors. Just my 2 cents worth Thanks for your comment Water. However, I really need arrays of arrays. It's a powerfull AutoIt feature and I see no reason to do without it. Anyway, I made my own UDF to manage arrays of arrays easily, and my problem is now solved. Thanks, anyway. PS : for people interested, here is the code: func VecSetVal(byref $aArray, $xVal, $iIndex, $iIndex2 = Default, $iIndex3 = Default, $iIndex4 = Default, $iIndex5 = Default) if ($iIndex2 <> Default) then ; recurse on multiple indexes VecSetVal($aArray[$iIndex], $xVal, $iIndex2, $iIndex3, $iIndex4, $iIndex5) else $aArray[$iIndex] = $xVal endif endfunc
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now