footswitch Posted October 6, 2007 Share Posted October 6, 2007 Hi there. I've done some research in this forum, regarding arrays within arrays, but in every example I found nothing different than this: ;Option 4, global return, php/preg_match_all() style $array = StringRegExp('F1oF2oF3o', '(F.o)*?', 4) for $i = 0 to UBound($array) - 1 $match = $array[$i] for $j = 0 to UBound($match) - 1 msgbox(0, "cRegExp Test with Option 4 - " & $i & ',' & $j, $match[$j]) Next Next Is $match=$array[$i] the only way to access the array inside $array[$i]? Is there no direct access like, for instance (this won't work)... - $array[$i][$j] - $array[$i].[$j] I'm currently working with many arrays of this type, and it would be so much easier if I hadn't to create new vars and 'For' cycles all the time, sometimes for the simplest math operations. Either way, I think it would be important to clarify this matter in the documentation, namely here (check out Data types in Arrays, in the end of the page). Thanks in advance for your time, folks. footswitch Link to comment Share on other sites More sharing options...
randallc Posted October 6, 2007 Share Posted October 6, 2007 Hi, I have looked at getting up a UDF to do this, since I realised jscript had such arrays.. My Array2d.au3 UDF has some sort of fast translation to and from "Array of Arrays", but I know that is not what you are after. Certainly no direct way in AutoIt; perhaps you could do the UDf for this quicker than me!? Best, randall PS What script or program language are you used to that did this...? not C++, I think? ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
footswitch Posted October 6, 2007 Author Share Posted October 6, 2007 (edited) PS What script or program language are you used to that did this...? not C++, I think?In Java, acessing a 2D array within another 2D array (2D array inside array[0][1]), turns out as array[0][1][x][y]. Well, since there seems to be no direct language access, UDFs might be the best way. I'll take a look into your UDFs. Thanks. P.S.: I still think this should be documented. I might post a link to this in the suggestions forum. (EDIT: font format) Edited October 6, 2007 by footswitch Link to comment Share on other sites More sharing options...
aslani Posted October 6, 2007 Share Posted October 6, 2007 (edited) How about this? Dim $vArray[3][3] = [["a", "b", "c"], [1, 2, 3], ["d", "e", "f"]] For $x = 0 to 2 For $y = 0 to 2 MsgBox(0, "$vArray[" & $x & "][" & $y & "]", $vArray[$x][$y]) Next Next EDIT: In Java, acessing a 2D array within another 2D array (2D array inside array[0][1]), turns out as array[0][1][x][y]. eeek! Yeah a UDF will definitely has to do all that work. Edited October 6, 2007 by aslani [font="Georgia"]Chances are, I'm wrong.[/font]HotKey trouble?Stringregexp GuideAutoIT Current Version Link to comment Share on other sites More sharing options...
footswitch Posted October 6, 2007 Author Share Posted October 6, 2007 Oh, I see. No, randall, that's not what I'm after. Oh gosh, do I hate doing those small UDFs just for my specific needs (well call them snippets). But I'm too lazy to go further than that anyways... lol Thanks again. footswitch Link to comment Share on other sites More sharing options...
footswitch Posted October 6, 2007 Author Share Posted October 6, 2007 How about this? Dim $vArray[3][3] = [["a", "b", "c"], [1, 2, 3], ["d", "e", "f"]] For $x = 0 to 2 For $y = 0 to 2 MsgBox(0, "$vArray[" & $x & "][" & $y & "]", $vArray[$x][$y]) Next NextoÝ÷ Ø@ÈMç}ì$yÖj"W^~)âµér«-¡Ú[ajÜ(®Oêº^jÉZ,¨»kzh¬²)à*h{KzÝý²('¢·ä®)àEèÅìZ^J¶§È¦¦W«jëh×6Dim $array[2]=["This is a string within an array",StringSplit("This is an array within an array"," ")] ; how to access any of those words from $array[1]? The thing is, I don't have a multidimensional array. I really have an array within an array, in AutoIt it's really a different thing. Link to comment Share on other sites More sharing options...
GioVit Posted October 6, 2007 Share Posted October 6, 2007 The Faster way to access an array inside another array is assign the array item that contain the array value to a temporary variable, i.e.: Dim $Array[2] = ["This is a string within an array",StringSplit("This is an array within an array"," ")] For $i = 0 to Ubound($Array) -1 if IsArray($Array[$i]) Then $aTmp = $Array[$i] MsgBox(64, "Array Inside Array Found", "$Array[" & $i &"] = SubArray[" & Ubound($aTmp) & "]") EndIf Next Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 6, 2007 Share Posted October 6, 2007 The Faster way to access an array inside another array is assign the array item that contain the array value to a temporary variable...That's actually the ONLY way to access an array stored as an array element. There is no syntax in AutoIt to pass subscripts to an inner array. The inner array must be read out as its own array variable before it can be operated on. 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 More sharing options...
randallc Posted October 6, 2007 Share Posted October 6, 2007 The Faster way to access an array inside another array is assign the array item that contain the array value to a temporary variable, i.e.: Dim $Array[2] = ["This is a string within an array",StringSplit("This is an array within an array"," ")] For $i = 0 to Ubound($Array) -1 if IsArray($Array[$i]) Then $aTmp = $Array[$i] MsgBox(64, "Array Inside Array Found", "$Array[" & $i &"] = SubArray[" & Ubound($aTmp) & "]") EndIf NextHi, Yes, That is his exact question in the first post; ie how to -avoid- that interim assign!; perhaps we're all just lazy! Best, randall ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 6, 2007 Share Posted October 6, 2007 You can provide an inner array as a ByRef array parameter without reading it out. Consider this demo:#include <array.au3> $sString = "This is my string." Dim $avParent[2] = [$sString, StringSplit($sString, " ")] _ArrayDisplay($avParent[1], "Debug: $avParent[1]") _ShowMeIndex2($avParent[1]) _ArraySort($avParent[1], 0, 1) _ArrayDisplay($avParent[1], "Debug: $avParent[1]") _ShowMeIndex2($avParent[1]) Func _ShowMeIndex2(ByRef $avInput) MsgBox(64, "_ShowMeIndex2", "Index [2] = " & $avInput[2]) EndFunc 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 More sharing options...
randallc Posted October 7, 2007 Share Posted October 7, 2007 (edited) Yes, So we lazy ones have our UDF after all! ; _ShowMeIndexPsaltyDS.au3 #include <array.au3> $sString = "This is my string." Dim $avParent[2] = [$sString, StringSplit($sString, " ") ] _ArrayDisplay($avParent[1], "Debug: $avParent[1]") MsgBox(64, "_SubArrayItem2", "Index [2];_SubArrayItem($avParent[1],2) = " & _SubArrayItem($avParent[1], 2)) _ArraySort($avParent[1], 0, 1) _ArrayDisplay($avParent[1], "Debug: $avParent[1]") MsgBox(64, "_SubArrayItem2", "Index [2];_SubArrayItem($avParent[1],2) = " & _SubArrayItem($avParent[1], 2)) Func _SubArrayItem(ByRef $avInput, $i_Index=0) if not IsArray($avInput) or not UBound($avInput,0)=1 then return seterror(1) if not IsInt($i_Index) or $i_Index<0 then $i_Index=0 if $i_Index>UBound($avInput)-1 then $i_Index=UBound($avInput)-1 Return $avInput[$i_Index] EndFunc ;==>_SubArrayItem Randall! Edited October 7, 2007 by randallc ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 7, 2007 Share Posted October 7, 2007 Here's a demo of a UDF that can make deep references into nested arrays by a syntax that is at least similar to what the OP was about. The demo create a 2D array ($avParent) as in an earlier post, where [n][0] is a string sentence, and [n][1] is a 1D nested array the words from the sentence. A function called _MakeNestedArray() then makes the nesting more complicated by splitting the 1D nested array into 2D with word in [n][0] and a 1D array of characters in the word in [n][1]. One more layer of complexity is added by then taking the 1D array of characters and splitting that into a 2D array with the character in [n][0] and its ASCII code in [n][1]. So we have a 2D array of characters, nested inside a 2D array of words, nested inside a 2D array of sentences. After generating the complex $avParent array, it demonstates the _ArrayGetNested() UDF by reading the following references out of $avParent: [1][1] = the array of words from the second sentence [1][1].[5][1] = the array of characters in the fifth word of the second sentence. [1][1].[5][1].[3][1] = the ASCII code of the third character in the fifth word of the second sentence. expandcollapse popup#include <array.au3> ; Create $avParent 2D array $sString1 = "This is my first string." $sString2 = "Here is your second string." Global $avParent[2][2] = [[$sString1, StringSplit($sString1, " ") ], [$sString2, StringSplit($sString2, " ") ]] ; At this point for example ; $avParent[1][0] = "Here is your second string." ; $avParent[1][1] = 1D StringSplit array of those words _MakeNestedArray() ; Make the array more complicated for demo $Answer1 = _ArrayGetNested($avParent, "[1][1]") _ArrayDisplay($Answer1, "Debug: $Answer1 = $avParent[1][1]") $Answer2 = _ArrayGetNested($avParent, "[1][1].[5][1]") _ArrayDisplay($Answer2, "Debug: $Answer2 = $avParent[1][1].[5][1]") $Answer3 = _ArrayGetNested($avParent, "[1][1].[5][1].[3][1]") MsgBox(64, "Answer", "$Answer3 = $avParent[1][1].[5][1].[3][1] = " & $Answer3) $Answer4 = _ArrayGetNested($Answer2, "[3][1]") MsgBox(64, "Answer", "$Answer4 = $Answer2[3][1] = " & $Answer4) ; ----------------------------------------------------- ; Function: _ArrayGetNested ; Purpose: Make a deep reference read into an array nested in other array(s) ; Call with: _ArrayGetNested(ByRef $avInput, $sRef) ; Where: $avInput = parent array to make reference into ; $sRef = Reference string, i.e. "[2][4].[6].[1][7][2]" ; On success returns the specified array element ; On failure sets @error ; Notes: Each level of array nesting is delimited by a period and can be 3D ; (3 subscripts) max for each level of nesting. ; Author: PsaltyDS at http://www.autoitscript.com/forum ; ----------------------------------------------------- Func _ArrayGetNested(ByRef $avInput, $sRef) Local $RET, $sNextRef = "" ; Break into dot delimited subscript sets Local $avRefSplit = StringSplit($sRef, ".") If $avRefSplit[0] > 1 Then $sNextRef = StringTrimLeft($sRef, StringInStr($sRef, ".")) ; Interpret subscript set [1] Local $avSubscripts = StringRegExp($avRefSplit[1], '(?s)\[(.*?)\]', 3) If @error Then Return SetError(1, 0, 0) ; Check for final reference or recurse If $avRefSplit[0] = 1 Then ; Final reference, return value Switch UBound($avSubscripts) Case 1 Return $avInput[$avSubscripts[0]] Case 2 Return $avInput[$avSubscripts[0]][$avSubscripts[1]] Case 3 Return $avInput[$avSubscripts[0]][$avSubscripts[1]][$avSubscripts[2]] Case Else Return SetError(1, 0, 0) EndSwitch Else ; Recurse to next level Switch UBound($avSubscripts) Case 1 $RET = _ArrayGetNested($avInput[$avSubscripts[0]], $sNextRef) Case 2 $RET = _ArrayGetNested($avInput[$avSubscripts[0]][$avSubscripts[1]], $sNextRef) Case 3 $RET = _ArrayGetNested($avInput[$avSubscripts[0]][$avSubscripts[1]][$avSubscripts[2]], $sNextRef) Case Else Return SetError(1, 0, 0) EndSwitch ; Return result from recursion SetError(@error) Return $RET EndIf EndFunc ;==>_ArrayGetNested ; ----------------------------------------------------- ; The _MakeNestedArray() function takes the $avParent array and embeds deeper nested arrays for the demo. ; ----------------------------------------------------- Func _MakeNestedArray() ; Split each 1D array of words into a 2D array with the words in [n][0] and a StringSplit 1D array characters in [n][1] For $p = 0 To UBound($avParent) - 1 $avTemp_A = $avParent[$p][1] Dim $avTemp_B[$avTemp_A[0] + 1][2] = [[$avTemp_A[0], ""]] For $b = 1 To $avTemp_B[0][0] $avTemp_B[$b][0] = $avTemp_A[$b] $avTemp_B[$b][1] = StringSplit($avTemp_A[$b], "") Next $avParent[$p][1] = $avTemp_B Next ; Split each 1D array of characters into a 2D array with the character in [n][0] and its ASCII code in [n][1] For $p = 0 To UBound($avParent) - 1 $avTemp_A = $avParent[$p][1] ; $avTemp_A = 2D array of words For $a = 1 To $avTemp_A[0][0] $avTemp_B = $avTemp_A[$a][1] ; $avTemp_B = 1D array of characters Dim $avTemp_C[$avTemp_B[0] + 1][2] = [[$avTemp_B[0], ""]] ; $avTemp_C will be 2D array of characters and their ASCII For $c = 1 To $avTemp_C[0][0] $avTemp_C[$c][0] = $avTemp_B[$c] $avTemp_C[$c][1] = Asc($avTemp_B[$c]) Next $avTemp_A[$a][1] = $avTemp_C $avParent[$p][1] = $avTemp_A Next Next EndFunc ;==>_MakeNestedArray ...now my head hurts. I'm going to bed. 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 More sharing options...
randallc Posted October 7, 2007 Share Posted October 7, 2007 OMG! So does that mimic Java nested arrays?; or some other language?.. randall ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 7, 2007 Share Posted October 7, 2007 OMG!So does that mimic Java nested arrays?; or some other language?..randallGood question -- I have no idea. I was just trying to mimic the syntax example in the OP. 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 More sharing options...
footswitch Posted October 7, 2007 Author Share Posted October 7, 2007 (edited) I was trying to describe what I felt when I came back here... It was something like... "omfg " PsaltyDS, before anything else, let me tell you this... This is f****ng brilliant. I can see randall felt the same way I'm going to take a look at this. Yes, it's pretty cool... and confusing (lol) @Randall, I don't know if this mimics another language (I can tell it's not Java's syntax, as you can see in my post above)... maybe C++? But it shows a nice 'object-ish' look! I'll be in touch! Thanks a LOT! (p.s. heck, why am I not receiving e-mails when i get replies?...) EDIT: "You can provide an inner array as a ByRef array parameter without reading it out." --> I felt stupid when I read this. It was so damn in front of my eyes. But gosh did you take that to the next level! Edited October 7, 2007 by footswitch Link to comment Share on other sites More sharing options...
footswitch Posted October 8, 2007 Author Share Posted October 8, 2007 Submitted to AutoIt Feature Requests (documentation update request). Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 8, 2007 Share Posted October 8, 2007 Thanks a LOT! Glad it helped. Exercises in ratiocination like that are how I learn the new stuff. Thanks for the puzzle. 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 More sharing options...
-Ultima- Posted October 8, 2007 Share Posted October 8, 2007 (edited) An equally workable solution (that handles arbitrarily-dimensioned arrays) would be as follows, I guess expandcollapse popup#include <array.au3> ; Create $avParent 2D array $sString1 = "This is my first string." $sString2 = "Here is your second string." Global $avParent[2][2] = [[$sString1, StringSplit($sString1, " ") ], [$sString2, StringSplit($sString2, " ") ]] ; At this point for example ; $avParent[1][0] = "Here is your second string." ; $avParent[1][1] = 1D StringSplit array of those words _MakeNestedArray() ; Make the array more complicated for demo Local $asPath = StringSplit("[1][1]", ".") $Answer1 = _ArrayPathGet($avparent, $asPath) _ArrayDisplay($Answer1, "Debug: $Answer1 = $avParent[1][1]") $asPath = StringSplit("[1][1].[5][1]", ".") $Answer2 = _ArrayPathGet($avParent, $asPath) _ArrayDisplay($Answer2, "Debug: $Answer2 = $avParent[1][1].[5][1]") $asPath = StringSplit("[1][1].[5][1].[3][1]", ".") $Answer3 = _ArrayPathGet($avParent, $asPath) MsgBox(64, "Answer", "$Answer3 = $avParent[1][1].[5][1].[3][1] = " & $Answer3) $asPath = StringSplit("[3][1]", ".") $Answer4 = _ArrayPathGet($Answer2, $asPath) MsgBox(64, "Answer", "$Answer4 = $Answer2[3][1] = " & $Answer4) ; ----------------------------------------------------- Func _ArrayPathGet(ByRef $array, ByRef $path, $depth = 1) Local $vVal = Execute("$array" & $path[$depth]) If $depth < $path[0] Then Return _ArrayPathGet($vVal, $path, $depth+1) Return $vVal EndFunc ; ----------------------------------------------------- ; ----------------------------------------------------- ; The _MakeNestedArray() function takes the $avParent array and embeds deeper nested arrays for the demo. ; ----------------------------------------------------- Func _MakeNestedArray() ; Split each 1D array of words into a 2D array with the words in [n][0] and a StringSplit 1D array characters in [n][1] For $p = 0 To UBound($avParent) - 1 $avTemp_A = $avParent[$p][1] Dim $avTemp_B[$avTemp_A[0] + 1][2] = [[$avTemp_A[0], ""]] For $b = 1 To $avTemp_B[0][0] $avTemp_B[$b][0] = $avTemp_A[$b] $avTemp_B[$b][1] = StringSplit($avTemp_A[$b], "") Next $avParent[$p][1] = $avTemp_B Next ; Split each 1D array of characters into a 2D array with the character in [n][0] and its ASCII code in [n][1] For $p = 0 To UBound($avParent) - 1 $avTemp_A = $avParent[$p][1] ; $avTemp_A = 2D array of words For $a = 1 To $avTemp_A[0][0] $avTemp_B = $avTemp_A[$a][1] ; $avTemp_B = 1D array of characters Dim $avTemp_C[$avTemp_B[0] + 1][2] = [[$avTemp_B[0], ""]] ; $avTemp_C will be 2D array of characters and their ASCII For $c = 1 To $avTemp_C[0][0] $avTemp_C[$c][0] = $avTemp_B[$c] $avTemp_C[$c][1] = Asc($avTemp_B[$c]) Next $avTemp_A[$a][1] = $avTemp_C $avParent[$p][1] = $avTemp_A Next Next EndFunc ;==>_MakeNestedArrayBe aware that I didn't bother with error checking, since it's just proof-of-concept quality code only. You might want to add the error checking for "production" code. Doing the whole StringSplit() thing before calling the function isn't absolutely necessary, and I could just as easily pass the path string as an argument itself, but it's a waste of resources to split the same string over and over during each recursive call. Edited October 8, 2007 by -Ultima- [ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ] Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 8, 2007 Share Posted October 8, 2007 Local $vVal = Execute("$array" & $path[$depth]) That's very interesting. I tried Eval(), which didn't work and lead to the longer method, but didn't think to try Execute(). 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 More sharing options...
footswitch Posted October 8, 2007 Author Share Posted October 8, 2007 Once again, thanks! Interesting approaches Link to comment Share on other sites More sharing options...
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