AnonymousX Posted March 29, 2017 Share Posted March 29, 2017 (edited) Hello, I have a program that stores settings in a 1D array. Someone had recommended that to save settings create an .ini file and write to it using IniWrite function. This works great but creates a 2D array. So when I try to recover settings things break because simply deleting a column doesn't convert a 2D to a 1D array, as I had hoped. Any simple ways of converting a 2D array to a 1D array? #include <Array.au3> Local $twoDarray[3][2] Local $oneDarray[3] $twoDarray [0][1] = "A" $twoDarray [1][1] = "B" $twoDarray [2][1] = "C" _ArrayColDelete($twoDarray,0) $oneDarray=$twoDarray; $oneDarray is now a 2D array [3][1] instead of just [3] _ArrayDisplay($twoDarray) _ArrayDisplay($oneDarray) Edited March 29, 2017 by AnonymousX Link to comment Share on other sites More sharing options...
InunoTaishou Posted March 29, 2017 Share Posted March 29, 2017 Not sure how you're able to create a 2d array using IniWrite, I think you left out a step. Perhaps you meant you get a 2d array using IniReadSection? If you're trying to store settings in an Ini file this is one of the favorite ways I use to load/save ini files expandcollapse popup#include <String.au3> #include <FileConstants.au3> #include <GUIConstants.au3> ; Array holding the Ini Key and the corresponding AutoIt variable name Global Const $INI_SETTINGS[][2] = [["String Val", "sStringVal"], ["Integer Val", "iIntVal"], ["Double Val", "dDoubleVal"], ["Boolean Val", "bBoolVal"]] Global $sStringVal = "" Global $iIntVal = 0 Global $dDoubleVal = 0.0 Global $bBoolVal = False LoadIniFile(@ScriptDir & "\Test.ini") Global $hMain = GUICreate("Example", 230, 130) Global $lblString = GUICtrlCreateLabel("String Val = ", 10, 10, 75, 20) Global $inpString = GUICtrlCreateInput($sStringVal, 85, 10, 125, 20) Global $lblInteger = GUICtrlCreateLabel("Integer Val = ", 10, 40, 75, 20) Global $inpInteger = GUICtrlCreateInput($iIntVal, 85, 40, 125, 20) Global $lblDouble = GUICtrlCreateLabel("Double Val = ", 10, 70, 75, 20) Global $inpDouble = GUICtrlCreateInput($dDoubleVal, 85, 70, 125, 20) Global $lblBool = GUICtrlCreateLabel("Boolean Val = ", 10, 100, 75, 20) Global $inpBool = GUICtrlCreateInput($bBoolVal, 85, 100, 125, 20) GUISetState(@SW_SHOW, $hMain) While (True) Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSE $sStringVal = GUICtrlRead($inpString) $iIntVal = GUICtrlRead($inpInteger) $dDoubleVal = GUICtrlRead($inpDouble) $bBoolVal = GUICtrlRead($inpBool) SaveToIniFile(@ScriptDir & "\Test.ini") Exit 0 EndSwitch WEnd Func LoadIniFile(Const $sIniFile) If (Not FileExists($sIniFile)) Then Return For $i = 0 To UBound($INI_SETTINGS) - 1 Local $vIniValue = IniRead($sIniFile, "Settings", $INI_SETTINGS[$i][0], "Default") If ($vIniValue == "Default" Or StringLen($vIniValue) = 0) Then ContinueLoop ; If the string value of the ini setting is the string "True" make it Boolean true If ($vIniValue = "True") Then $vIniValue = True ; If the string value of the ini setting is the string "False" make it Boolean false If ($vIniValue = "False") Then $vIniValue = False ; Assign to the variable the value read Assign($INI_SETTINGS[$i][1], $vIniValue) Next EndFunc ;==>LoadIniFile Func SaveToIniFile(Const $sIniFile) ; Open Ini File for overwrite ; That's correct, we are not going to use IniWrite because everything can be written to the Ini file using the $INI_SETTINGS array Local $hIniFile = FileOpen($sIniFile, $FO_OVERWRITE) ; Beginning of the Ini file Local $sSettings = "[Settings]" & @CRLF ; Length of the longest Key value, used purely to make the ini file look pretty.... Local $iMaxLength = 0 ; Get the longest length of a string For $i = 0 To UBound($INI_SETTINGS) - 1 $iMaxLength = Max(StringLen($INI_SETTINGS[$i][0]) + 1, $iMaxLength) Next ; Create the ini file string For $i = 0 To UBound($INI_SETTINGS) - 1 Local $sPadding = StringReplace(_StringRepeat(" ", $iMaxLength - StringLen($INI_SETTINGS[$i][0])), " ", " ") $sSettings &= $INI_SETTINGS[$i][0] & StringReplace($sPadding, " ", " ") & " = " & Eval($INI_SETTINGS[$i][1]) & @CRLF Next ; Write the file (removing the last @CRLF) and close FileWrite($hIniFile, StringTrimRight($sSettings, 2)) Return FileClose($hIniFile) EndFunc ;==>SaveToIniFile Func Max(Const $lhs, Const $rhs) Return ($lhs > $rhs ? $lhs : $rhs) EndFunc ;==>Max I store all of the Key values from the Ini file in the [n][0] element and the autoit variable in the [n][1] element of a 2d array. AnonymousX 1 Link to comment Share on other sites More sharing options...
Subz Posted March 29, 2017 Share Posted March 29, 2017 (edited) To convert the 2D Array to a 1D Array you could just use: #include <Array.au3> Local $twoDarray[3][2] Local $oneDarray[1] $twoDarray [0][1] = "A" $twoDarray [1][1] = "B" $twoDarray [2][1] = "C" For $i = 0 To UBound($twoDarray) - 1 _ArrayAdd($oneDarray, $twoDarray[$i][1]) Next $oneDarray[0] = UBound($oneDarray) - 1 _ArrayDisplay($twoDarray) _ArrayDisplay($oneDarray) Edited March 29, 2017 by Subz AnonymousX 1 Link to comment Share on other sites More sharing options...
AnonymousX Posted March 29, 2017 Author Share Posted March 29, 2017 12 minutes ago, InunoTaishou said: Not sure how you're able to create a 2d array using IniWrite, I think you left out a step. Perhaps you meant you get a 2d array using IniReadSection? If you're trying to store settings in an Ini file this is one of the favorite ways I use to load/save ini files I store all of the Key values from the Ini file in the [n][0] element and the autoit variable in the [n][1] element of a 2d array. 3 Maybe I'm not explaining it correctly but from what I see the values in the Ini file are stored in an [n][2] matrix. When I read off the matrix I get an [n][2] array which I'm referring to as a 2D array as you have 2 components ( [Columns][Rows]). I created the following code to demonstrate the issue better. Run the code once and the message box works because you're dealing with a regular 1D array. Run the code twice and now it will not display the message box because you are dealing with 2D array. You can check this by switching the uncommented message box and see that now this will work. I know worst case I have the option of easily just creating a for loop and going through the 2D array and having it 1 by 1 move everything I want into a 1D array, but I was wondering if there was a way to use code similar to twoDarray=oneDarray and just copy over relevant information as it's a [n][0] now, instead of [n][1]. expandcollapse popup#include <Array.au3> #include <FileConstants.au3> $hFile = @ScriptDir&"\test.ini" $setting_size = 3 Global $oneDarray[3] If not FileExists($hFile) Then DirCreate($hFile) Save($hFile) Else load($hFile) EndIf ;~ _ArrayDisplay($oneDarray) ;~ MsgBox(0,"",$oneDarray[0][0]);This works because during the saving it became a 2D array MsgBox(0,"",$oneDarray[0]); I want this to work because I only want to deal with a 1D array Func save($hFile) $oneDarray [0] = "A" $oneDarray [1] = "B" $oneDarray [2] = "D" ;~ _ArrayDisplay($oneDarray) Local $temparray[$setting_size] For $i = 0 To $setting_size - 1 Step 1 $temparray[$i] = $i IniWrite($hFile & '\test.ini', 'test', $temparray[$i], $oneDarray[$i]) Next EndFunc Func load($hFile) Local $asettings = IniReadSection($hFile & '\test.ini', 'test') $asettings[0][0] = "" $asettings[0][1] = "" $asettings = DeleteEmptyRows($asettings) _ArrayColDelete($asettings, 0) $oneDarray = $asettings EndFunc Func DeleteEmptyRows($aArray) ;Takes in an array (accepts 2D) and deletes all blank elements Local $Rows = UBound($aArray, 1) Local $Cols = UBound($aArray, 2) Local $aTemp[$Rows][$Cols] Local $not_empty Local $Count = 0 ;Loop through rows For $Y = 0 To $Rows - 1 $not_empty = 0 ;Loop through columns For $X = 0 To $Cols - 1 ;Copy all columns to temp array even if they are all empty $aTemp[$Count][$X] = $aArray[$Y][$X] ;If even one column contains data, make sure it doesn't get deleted If $aArray[$Y][$X] <> "" Then $not_empty = BitOR($not_empty, 1) Next ;If the row has any data, increment, else keep overwriting last row until it contains something If $not_empty Then $Count += 1 Next ReDim $aTemp[$Count][$Cols] Return $aTemp EndFunc ;==>DeleteEmptyRows Link to comment Share on other sites More sharing options...
InunoTaishou Posted March 29, 2017 Share Posted March 29, 2017 (edited) I thought so, you're loading the ini file using IniReadSection, which returns a 2d array. You could convert the 2d array to a 1d like Subz did or use a loop for IniRead (one value at a time). Subz example would be better, and my example would work as well for loading/saving. Edited March 29, 2017 by InunoTaishou Link to comment Share on other sites More sharing options...
AnonymousX Posted March 29, 2017 Author Share Posted March 29, 2017 (edited) 52 minutes ago, Subz said: To convert the 2D Array to a 1D Array you could just use: #include <Array.au3> Local $twoDarray[3][2] Local $oneDarray[1] $twoDarray [0][1] = "A" $twoDarray [1][1] = "B" $twoDarray [2][1] = "C" For $i = 0 To UBound($twoDarray) - 1 _ArrayAdd($oneDarray, $twoDarray[$i][1]) Next $oneDarray[0] = UBound($oneDarray) - 1 _ArrayDisplay($twoDarray) _ArrayDisplay($oneDarray) My Man Subz, always with just what I need! Thanks! Thanks Inuno Taishou too! Edited March 29, 2017 by AnonymousX Link to comment Share on other sites More sharing options...
Malkey Posted March 29, 2017 Share Posted March 29, 2017 Here is a better logical order of commands for your post #1 example. #include <Array.au3> Local $twoDarray[3][2] $twoDarray[0][1] = "A" $twoDarray[1][1] = "B" $twoDarray[2][1] = "C" Local $oneDarray = $twoDarray ; $oneDarray is now a 2D array [3][2], and, $twoDarray remains an identical 2D array [3][2]. _ArrayColDelete($oneDarray, 0) ; $oneDarray is now a 1D array _ArrayDisplay($twoDarray, "2D array") _ArrayDisplay($oneDarray, "1D array") Link to comment Share on other sites More sharing options...
Subz Posted March 29, 2017 Share Posted March 29, 2017 @Malkey I think AnonymousX was just pointing out that the $oneDarray is still a 2D array but with one column and so can't be referenced as a 1D array. Hope that made sense. AnonymousX 1 Link to comment Share on other sites More sharing options...
AnonymousX Posted March 30, 2017 Author Share Posted March 30, 2017 @Malkey Subz is correct. Ultimately it seemed like the easiest way to solve the problem was just create a for loop and pasted in the values from the 1 column of the 2D array. However, I was being stubborn and trying to find a way to just make the 2D array become a 1D array which is achievable via Subz's code. Link to comment Share on other sites More sharing options...
Malkey Posted March 30, 2017 Share Posted March 30, 2017 I agree, Subz is correct. 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