nikink Posted February 27, 2008 Share Posted February 27, 2008 (edited) Hi folks, I have a little project where I have an Inifile like so: [section] IniKey1=val1.1,@keyword@keyword2,val1.2 IniKey2=val2.1,@keyword2,val2.2 IniKey3=val3.1,@keyword3@keyword2,val3.2 IniKey4=val4.1,,val4.2 IniKey5=val5.1,@keyword3@keyword4,val5.2 The Section can have a variable number of keys, and each key can have a variable number of keywords. I want to be able to identify all keywords (including 'blank') and then be able to find all IniKeys with that keyword. My first thought was that this would necessitate an Array of Arrays, and then I thought that a 3D Array would be more efficient / faster. So I have a little Script that finds all the keywords and puts them into an Array. Then I've tried going through the 2D array returned by IniReadSection and putting all the inikeys and inivalues (including the keywords) into the 2nd and 3rd dimension of the 3d Array. The Keywords becomes the 1st Dimension. It's become very confusing!!! My code so far kinda works, but doesn't seem to be filling the 3D array - many places are remaining unfilled, and the dimension sizes seem a bit wonky too, which explains at least some of the blank spaces... So, I'm here to ask if anyone has either a better way to do this than a 3D array, or more experience with filling such arrays from a 1D + a 2D array combination. My code so far is here: expandcollapse popup;So, inireadsection to put it all into one big array ;cycle through the array and find each unique keyword ;create an array for each keyword? Not sure that's possible #include <Array.au3> dim $aTest[3][3] $aTest[0][0] = "inikey1" $aTest[0][1] = "@word1@word2" $aTest[0][2] = "inival1" $aTest[1][0] = "inikey2" $aTest[1][1] = "@word2" $aTest[1][2] = "inival2" $aTest[2][0] = "inikey3" $aTest[2][1] = "@word1@word3" $aTest[2][2] = "inival3" Global $results[1][1][1] dim $aKeyWords[1] For $i = 0 To Ubound($aTest,1)-1 $aw = StringSplit($aTest[$i][1], "@") ;ConsoleWrite(Ubound($aKeyWords) & @CR) ;ConsoleWrite(UBound($aw) & @CR) If UBound($aw) > 1 Then ReDim $aKeyWords[Ubound($aKeyWords)+UBound($aw)-1] ;ConsoleWrite(@TAB & Ubound($aKeyWords) & @CR) ;ConsoleWrite(@TAB & Ubound($aw) & @CR) For $j = 2 to UBound($aw)-1 ; ConsoleWrite($j & ":"& $aw[$j] & @CR) ;ConsoleWrite(@TAB & $aTest[$i][0] & @CR) ;ConsoleWrite(@TAB & $aTest[$i][2] & @CR) ; ConsoleWrite(@TAB & Ubound($aKeyWords)+$j-UBound($aw) & @CR) $aKeyWords[Ubound($aKeyWords)+$j-UBound($aw)] = $aw[$j] Next EndIf Next ;_ArrayDisplay($aKeyWords) $aKeyWords = _ArrayUnique($aKeyWords) _ArrayDelete($aKeyWords, 0) ;_ArrayDisplay($aTest) ReDim $results[Ubound($aKeyWords)][1][Ubound($aTest,2)];[Ubound($aTest,1)][Ubound($aTest,2)] For $i = 0 To Ubound($results)-1 $results[$i][0][0] = $aKeyWords[$i] If $results[$i][0][0] = "" Then ConsoleWrite("Results = Blank... " & @CR) ConsoleWrite("$i = " & $i & " : $results[$i][0][0] = " & $results[$i][0][0] & @CR) For $j = 0 To Ubound($aTest,1)-1 If $results[$i][0][0] = "" Or StringInStr($aTest[$j][1], $results[$i][0][0]) Then ReDim $results[Ubound($results,1)][Ubound($results,2)+1][Ubound($results,3)] $results[$i][$j+1][0] = $aTest[$j][0] ConsoleWrite("$i = " & $i & " $j = " & $j & " : $results[$i][$j][0] = " & $results[$i][$j+1][0] & @CR) For $k = 1 To Ubound($aTest,2)-1 $results[$i][$j+1][$k-1] = $aTest[$j][$k] ConsoleWrite("$i = " & $i & " $j = " & $j & " $k = " & $k & " : $results[$i][$j][$k] = " & $results[$i][$j+1][$k-1] & @CR) Next Else ;ConsoleWrite($results[$i][0][0] & " not found in " & $aTest[$j][0] & @CR) EndIf Next Next _VarDumpByRef($results, "CW") Func _ArrayUnique(ByRef $aArray, $vDelim = '', $iBase = 1, $iUnique = 1) If $vDelim = '' Then $vDelim = Chr(01) Local $sHold For $iCC = $iBase To UBound($aArray) - 1 If Not StringInStr($vDelim & $sHold, $vDelim & $aArray[$iCC] & $vDelim, $iUnique) Then _ $sHold &= $aArray[$iCC] & $vDelim Next Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim) EndFunc #cs -------------------------------------------------------------------------------------------------------------------- Syntax: _VarDumpByRef(ByRef $vVar, $vDumpType) Description: This function displays information about the variable given, as well as it's contents (if applicable/available). Parameters: $vVar - The variable to display. $vDumpType - How to dump the variable information. See remarks for available flags. Return values: String containing the information about the variable. Author: Rob Saunders (rob at therks dot com) Remarks: Arrays and DllStructs are fully explored and returned regardless of how many subscripts or dimensions there are. This function will also properly display arrays within arrays, a feature not entirely supported by AutoIt. The variable must be passed by reference for this function. This means _VarDumpByRef('Hello') will error. If you want to test an expression instead of a variable use _VarDump('Expression'). #ce -------------------------------------------------------------------------------------------------------------------- Func _VarDumpByRef(ByRef $vVar, $vDumpType = Default, $sIndent = '') Local $sVarDump Local $sVarType = VarGetType($vVar) Switch $sVarType Case 'DllStruct' $sVarDump = 'DllStruct(' & @CRLF & _VarDumpStruct($vVar, $sIndent & @TAB) & @CRLF & $sIndent & ')' Case 'Array' $sVarDump = 'Array(' & @CRLF & _VarDumpArray($vVar, $sIndent & @TAB) & @CRLF & $sIndent & ')' Case 'Binary' $sVarDump = 'Binary(' & BinaryLen($vVar) & ') ' & $vVar Case 'Object' $sVarDump = 'Object(' & ObjName($vVar) & ')' Case 'String' $sVarDump = 'String(' & StringLen($vVar) & ') ' & $vVar Case Else $sVarDump = $sVarType & '(' & $vVar & ')' EndSwitch Switch $vDumpType Case 1, 'ConsoleWrite', 'Console', 'CW' ConsoleWrite($sVarDump & @CRLF) Case 2, 'MsgBox', 'Msg', 'Box' MsgBox(0x2040, 'VarDisplay', $sVarDump) Case 3, 'ToolTip', 'Tip' ToolTip($sVarDump) Case 4, 'Clip', 'Clipboard' ClipPut($sVarDump) Case 5, 'GUI', 'Text' Local Const $__WS_OVERLAPPEDWINDOW = 0xCF0000 Local Const $__GUI_DOCKBORDERS = 102 Local Const $__GUI_EVENT_CLOSE = -3 Local $iGUIOnEventMode = Opt('GUIOnEventMode', 0) Local $guiVarDisplay = GUICreate('VarDisplay', 300, 200, Default, Default, $__WS_OVERLAPPEDWINDOW) GUICtrlCreateEdit($sVarDump, 0, 0, 300, 200) GUICtrlSetResizing(-1, $__GUI_DOCKBORDERS) GUISetState(@SW_SHOW, $guiVarDisplay) Do Until GUIGetMsg() = $__GUI_EVENT_CLOSE GUIDelete($guiVarDisplay) Opt('GUIOnEventMode', $iGUIOnEventMode) EndSwitch Return $sVarDump EndFunc A way to visualise what's going on would be helpful, but apart from my ConsoleWrites and the _VarDumpByRef I haven't got one. Hope you can help! Edited February 27, 2008 by nikink Link to comment Share on other sites More sharing options...
Xenobiologist Posted February 27, 2008 Share Posted February 27, 2008 Hi, so you need to see /visualize the content of your 3d array? Mega Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
Malkey Posted February 27, 2008 Share Posted February 27, 2008 Global $results[1][1][1]I will try to explain the humor in this declaration. A two dimensional (2D)array can be visualized as a spreadsheet with rows and columns - as in Excel. Each cell in the spreadsheet is a variable which can store data. So it really should be called an array of variables in which data can be stored and accessed. A three dimensional (3D) array can be visualized as a spreadsheet with rows and columns, and on each cell of that speadsheet is a stack of more cells. It would look like a cube made up of individual cells. So the height of the cube would be rows, the width let be columns and depth is stacks of cells. $results[1][1][1] = $results [Number of rows] [Number of columns] [number of stacks] You have declared one cell in three dimensional way. The only cell or variable available to store data in that 3d array is $results[0][0][0] . This is the same as an ordinary, every day, single variable, as in "Dim $aKeyWords " . It's not necessary to declare $aKeyWords[1], which is a one cell single (one) dimensional array. For $i = 0 To Ubound($results)-1Ubound($results) = 1 Ubound($results)-1 = 0 So, "For $i = 0 To Ubound($results)-1" is the same as "For $i = 0 To 0" I did a forum search and came across http://www.autoitscript.com/forum/index.ph...st&p=410283 It shows a way if entering data into a 3D array I had not seen before. One other thing, a four dimensonal array. It can be visualized as two spreadsheets. $array[one dimension][Two dimension] [three dimension][ four dimension] On each cell of a spreadsheet is another spreadsheet. [one dimension(row)][Two dimension(column)] is the address of the cell of another spreadsheet which has data stored at [three dimension(row)][ four dimension(column)]. Hope this helped. Link to comment Share on other sites More sharing options...
PsaltyDS Posted February 27, 2008 Share Posted February 27, 2008 Hi folks, I have a little project where I have an Inifile like so: [section] IniKey1=val1.1,@keyword@keyword2,val1.2 IniKey2=val2.1,@keyword2,val2.2 IniKey3=val3.1,@keyword3@keyword2,val3.2 IniKey4=val4.1,,val4.2 IniKey5=val5.1,@keyword3@keyword4,val5.2 The Section can have a variable number of keys, and each key can have a variable number of keywords. I want to be able to identify all keywords (including 'blank') and then be able to find all IniKeys with that keyword. My first thought was that this would necessitate an Array of Arrays, and then I thought that a 3D Array would be more efficient / faster. So I have a little Script that finds all the keywords and puts them into an Array. Then I've tried going through the 2D array returned by IniReadSection and putting all the inikeys and inivalues (including the keywords) into the 2nd and 3rd dimension of the 3d Array. The Keywords becomes the 1st Dimension. It's become very confusing!!! My code so far kinda works, but doesn't seem to be filling the 3D array - many places are remaining unfilled, and the dimension sizes seem a bit wonky too, which explains at least some of the blank spaces... So, I'm here to ask if anyone has either a better way to do this than a 3D array, or more experience with filling such arrays from a 1D + a 2D array combination. A way to visualise what's going on would be helpful, but apart from my ConsoleWrites and the _VarDumpByRef I haven't got one. Hope you can help! This will read an INI file and put it all in a single 3D array: expandcollapse popup$sINI = FileOpenDialog("Read INI file to 3D array", "", "INI Files (*.ini)", 1 + 2) If @error Then Exit $avResults = _IniReadToArray($sINI) _ArrayDisplay3D($avResults) Func _IniReadToArray($sIniFile) ; Read all section names Local $avSections = IniReadSectionNames($sIniFile) ; Find max count of keys Local $avSecData, $iMaxCnt = 0 For $s = 1 To $avSections[0] $avSecData = IniReadSection($sIniFile, $avSections[$s]) If $avSecData[0][0] > $iMaxCnt Then $iMaxCnt = $avSecData[0][0] Next ; Create 3D array Local $avRET[$avSections[0] + 1][$iMaxCnt + 1][2] $avRET[0][0][0] = $avSections[0] ; Sections count for the file ; Fill array For $s = 1 To $avSections[0] $avSecData = IniReadSection($sIniFile, $avSections[$s]) $avRET[$s][0][0] = $avSecData[0][0] ; Key count for this section $avRET[$s][0][1] = $avSections[$s] ; Section name For $k = 1 To $avSecData[0][0] $avRET[$s][$k][0] = $avSecData[$k][0] ; Key name $avRET[$s][$k][1] = $avSecData[$k][1] ; Value Next Next ; Return results Return $avRET EndFunc ;==>_IniReadToArray Func _ArrayDisplay3D($avInput) Local $sMsg = "" For $a = 0 To UBound($avInput) - 1 For $b = 0 To UBound($avInput, 2) - 1 For $c = 0 To UBound($avInput, 3) - 1 $sMsg &= "[" & $a & "][" & $b & "][" & $c & "] = " & $avInput[$a][$b][$c] & @CRLF Next Next Next Local $PID = Run("notepad.exe") WinWait("Untitled - Notepad") $hWin = WinGetHandle("Untitled - Notepad") ControlSetText($hWin, "", "Edit1", $sMsg) EndFunc ;==>_ArrayDisplay3D It should have more error checking, but demonstrates the technique. The basic difference is determining the sized of the first and second dimensions ahead of time, so the 3d array is declared once at the right size. Although it has to read the file through twice to determine the max key count before dimensioning the 3D array, this is still cleaner and maybe about as fast as all the REDIM work you were doing the hard way. 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...
PsaltyDS Posted February 27, 2008 Share Posted February 27, 2008 I will try to explain the humor in this declaration.A two dimensional (2D)array can be visualized as a spreadsheet with rows and columns - as in Excel. Each cell in the spreadsheet is a variable which can store data. So it really should be called an array of variables in which data can be stored and accessed.A three dimensional (3D) array can be visualized as a spreadsheet with rows and columns, and on each cell of that speadsheet is a stack of more cells.That assumes the extra dimension is added at the end of the index list. If you assume the extra dimension is at the BEGINING of the list, then the analogy is cleaner: 1. A 2D array is like a spreadsheet, with Rows and Columns2. A 3D array is like a workbook with multiple sheets, and each sheet has Rows/Columns.Much easier that way, isn't it? 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...
nikink Posted February 27, 2008 Author Share Posted February 27, 2008 Thankyou all! I will look through the advice you've given and try to understand it more than I do. Once I've done that I'll post more questions if I need to... which, given my limited understanding now, is quite likely! Link to comment Share on other sites More sharing options...
Kip Posted February 27, 2008 Share Posted February 27, 2008 I will try to explain the humor in this declaration. A two dimensional (2D)array can be visualized as a spreadsheet with rows and columns - as in Excel. Each cell in the spreadsheet is a variable which can store data. So it really should be called an array of variables in which data can be stored and accessed. A three dimensional (3D) array can be visualized as a spreadsheet with rows and columns, and on each cell of that speadsheet is a stack of more cells. It would look like a cube made up of individual cells. So the height of the cube would be rows, the width let be columns and depth is stacks of cells. $results[1][1][1] = $results [Number of rows] [Number of columns] [number of stacks] You have declared one cell in three dimensional way. The only cell or variable available to store data in that 3d array is $results[0][0][0] . This is the same as an ordinary, every day, single variable, as in "Dim $aKeyWords " . It's not necessary to declare $aKeyWords[1], which is a one cell single (one) dimensional array.I dont think its humor. He/she uses ReDim to increase the size of the array. That makes it "Advanced" instead of Humor. MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. 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