erifash Posted July 26, 2005 Share Posted July 26, 2005 Hi, I have been trying to create a better version of _ArrayToString() and have succeeded but now I am having trouble creating a _StringToArray() function. What's different about these functions is that they support two-dimensional arrays and that's what I need in order to convert a table into a string then write to a file. Here's what I have so far: _ArrayToString() : Works! _StringToArray() : Broken... expandcollapse popupFunc _ArrayToString(ByRef $aArray, $sDelim = "#$@") If not IsArray($aArray) Then SetError(1) Return "" EndIf Local $iDim = UBound($aArray, 0), $iBound = UBound($aArray, 1) - 1, $sArray = $iDim & $sDelim & $iBound, $i, $a, $b Select Case $iDim = 1 Local $iBound = UBound($aArray, 1) - 1 For $i = 0 to $iBound If not IsString($aArray[$i]) Then SetError(2) Return 0 EndIf $sArray = $sArray & $sDelim & $aArray[$i] Next Case $iDim = 2 Local $iBound2 = UBound($aArray, 2) - 1, $sArray = $sArray & $sDelim & $iBound2 For $b = 0 to $iBound2 For $a = 0 to $iBound If not IsString($aArray[$a][$b]) Then SetError(2) Return "" EndIf $sArray = $sArray & $sDelim & $aArray[$a][$b] Next Next EndSelect Return $sArray EndFunc Func _StringToArray(ByRef $sArray, $sdelim = "#$@") If not IsString($sArray) Then SetError(1) Return "" EndIf Local $aSplit = StringSplit($sArray, $sDelim, 1), $iDim = $aSplit[1], $iBound = $aSplit[2], $i, $a, $b Dim $aArray Select Case $iDim = 1 Local $aArray[$iBound + 1] For $i = 3 to $aSplit[0] If not IsString($aSplit[$i]) Then SetError(2) Return 0 EndIf $aArray[$i - 3] = $aSplit[$i] Next Case $iDim = 2 Local $iBound2 = $aSplit[3], $aArray[$iBound + 1][$iBound2 + 1] For $b = 4 to $aSplit[0] $aArray[$a - 4][$b - 4] = $aSplit[$b] If IsInt( ( $b - 4 ) / $iBound2 ) Then For $a = $b to $iBound2 $aArray[$a - 4][$b - 4] = $aSplit[$a] Next $b = $b + $iBound2 EndIf Next EndSelect Return $aArray EndFunc Any help or suggestions would be greatly appreciated! My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver Link to comment Share on other sites More sharing options...
blindwig Posted July 26, 2005 Share Posted July 26, 2005 Trying to understand what exactly you want to do... Can you give us some example arrays, and what you want the string to look like? Also, can you give us some sample strings, and the expected arrays that would be output? My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
seandisanti Posted July 26, 2005 Share Posted July 26, 2005 Hi, I have been trying to create a better version of _ArrayToString() and have succeeded but now I am having trouble creating a _StringToArray() function. What's different about these functions is that they support two-dimensional arrays and that's what I need in order to convert a table into a string then write to a file. Here's what I have so far:_ArrayToString() : Works!_StringToArray() : Broken...expandcollapse popupFunc _ArrayToString(ByRef $aArray, $sDelim = "#$@") If not IsArray($aArray) Then SetError(1) Return "" EndIf Local $iDim = UBound($aArray, 0), $iBound = UBound($aArray, 1) - 1, $sArray = $iDim & $sDelim & $iBound, $i, $a, $b Select Case $iDim = 1 Local $iBound = UBound($aArray, 1) - 1 For $i = 0 to $iBound If not IsString($aArray[$i]) Then SetError(2) Return 0 EndIf $sArray = $sArray & $sDelim & $aArray[$i] Next Case $iDim = 2 Local $iBound2 = UBound($aArray, 2) - 1, $sArray = $sArray & $sDelim & $iBound2 For $b = 0 to $iBound2 For $a = 0 to $iBound If not IsString($aArray[$a][$b]) Then SetError(2) Return "" EndIf $sArray = $sArray & $sDelim & $aArray[$a][$b] Next Next EndSelect Return $sArray EndFunc Func _StringToArray(ByRef $sArray, $sdelim = "#$@") If not IsString($sArray) Then SetError(1) Return "" EndIf Local $aSplit = StringSplit($sArray, $sDelim, 1), $iDim = $aSplit[1], $iBound = $aSplit[2], $i, $a, $b Dim $aArray Select Case $iDim = 1 Local $aArray[$iBound + 1] For $i = 3 to $aSplit[0] If not IsString($aSplit[$i]) Then SetError(2) Return 0 EndIf $aArray[$i - 3] = $aSplit[$i] Next Case $iDim = 2 Local $iBound2 = $aSplit[3], $aArray[$iBound + 1][$iBound2 + 1] For $b = 4 to $aSplit[0] $aArray[$a - 4][$b - 4] = $aSplit[$b] If IsInt( ( $b - 4 ) / $iBound2 ) Then For $a = $b to $iBound2 $aArray[$a - 4][$b - 4] = $aSplit[$a] Next $b = $b + $iBound2 EndIf Next EndSelect Return $aArray EndFuncAny help or suggestions would be greatly appreciated! <{POST_SNAPBACK}>sorry, just trying to understand... if you turn a 2 dimensional array into a string, would it create 2 strings? and you want to turn 2 strings into a two dimensional array? seems like once you have a working algo for multiples, it wouldn't be difficult to really expand upon it so that it would work for more than 2? Still not really seeing why you'd want to do that though... i know 'why' is a silly question, but just have to ask... Link to comment Share on other sites More sharing options...
erifash Posted July 26, 2005 Author Share Posted July 26, 2005 (edited) Okay, here is what works: (2 dimensionals don't work);example array to string, 1 dimensional Dim $a[3] $a[0] = "[0]" $a[1] = "[1]" $a[2] = "[2]" $s = _ArrayToString($a, "|") ;override default MsgBox(0, "a2s 1d", $s) $a2 = _StringToArray($s, "|") MsgBox(0, "s2a 1d", _Test(_ArrayCompare($a, $a2), "equal", "not equal")) Func _ArrayCompare(ByRef $aArr, ByRef $aArr2) Local $iBound = UBound($aArr, 0), $iBound2 = UBound($aArr2, 0), $i If $iBound <> $iBound2 Then Return 0 For $i = 0 to $iBound - 1 If $aArr[$i] <> $aArr2[$i] Then Return 0 Next Return 1 EndFunc Func _Test($b_Test, $v_True = 1, $v_False = 0) If $b_Test Then Return $v_True Return $v_False EndFuncI hope that answered your question blindwig.sorry, just trying to understand... if you turn a 2 dimensional array into a string, would it create 2 strings? and you want to turn 2 strings into a two dimensional array? seems like once you have a working algo for multiples, it wouldn't be difficult to really expand upon it so that it would work for more than 2? Still not really seeing why you'd want to do that though... i know 'why' is a silly question, but just have to ask...<{POST_SNAPBACK}>1. No, it would not create two strings.2. No, it specifies the ubounds of the array in the string so it can re-create the array.3. Yes, exactly.4. Why: I want to write some data that is stored in a binary tree (using the UDF blindwig wrote), converted into a two-dimensional array, converted into a string, then written to a file. I want to be able to retrieve that information later. That is why I wanted to create these functions. Edited July 26, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver Link to comment Share on other sites More sharing options...
erifash Posted July 26, 2005 Author Share Posted July 26, 2005 (edited) Okay, I have figured out my options: 1. Seperate each second dimension with a different character. 2. Bash my head in trying to figure out how to do it the "proper" way. 3. Wait for someone to help me out. I think i'll take the first one, but still wait on the third one in case there are breakthroughs. I don't really feel like hurting myself lol . I will update my first post with the new functions (once I make them) unless someone still wants the old ones. Edited July 26, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver Link to comment Share on other sites More sharing options...
erifash Posted July 26, 2005 Author Share Posted July 26, 2005 No go. I can't figure out how to do this so I just settled on something specifically suited for what I want to accomplish. My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver Link to comment Share on other sites More sharing options...
blindwig Posted July 26, 2005 Share Posted July 26, 2005 Going from your example, you can use StringSplit and _ArrayToString() in Array.au3 to do 1d arrays. How are you expecting to do 2d arrays? Are you trying to use the same delimiter for both dimensions? My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
mother9987 Posted July 26, 2005 Share Posted July 26, 2005 This is just rough and dirty, but should work up to 4 dimensions: expandcollapse popupDim $a[ 5 ][ 4 ][ 3 ], $i, $j, $k, $c = 0 For $i = 0 to 4 For $j = 0 to 3 For $k = 0 to 2 $a[ $i ][ $j ][ $k ] = Chr( 48 + $c ) $c += 1 Next Next Next $s = _ArrayMDtoString( $a ) MsgBox( 0, "Useless", $s ) $t = _StringtoArrayMD( $s ) MsgBox( 0, "Useless", $s & @CRLF & _ArrayMDtoString( $t ) ) Func _ArrayMDtoString( ByRef $aData, $sDelim="," ) If StringLen( $sDelim ) <> 1 Then SetError( 1 ) Return "" EndIf If UBound( $aData, 0) = 0 Then Return "0" & $sDelim & $aData EndIf Local $sRet, $iDim, $i, $Counter $iDim = UBound( $aData, 0 ) Local $iDims[ $iDim ], $iLoc[ $iDim ] $sRet = String( $iDim ) & $sDelim For $i=1 to $iDim $sRet &= UBound( $aData, $i ) & $sDelim $iDims[ $i - 1 ] = UBound( $aData, $i ) $iLoc[ $i - 1 ] = 0 Next While $iLoc[0] < $iDims[0] Select Case $iDim = 1 $sRet &= $aData[ $iLoc[ 0 ] ] & $sDelim Case $iDim = 2 $sRet &= $aData[ $iLoc[ 0 ] ][ $iLoc[ 1 ] ] & $sDelim Case $iDim = 3 $sRet &= $aData[ $iLoc[ 0 ] ][ $iLoc[ 1 ] ][ $iLoc[ 2 ] ] & $sDelim Case $iDim = 4 $sRet &= $aData[ $iLoc[ 0 ] ][ $iLoc[ 1 ] ][ $iLoc[ 2 ] ][ $iLoc[ 3 ] ] & $sDelim EndSelect $iLoc[ $iDim - 1 ] +=1 For $i = $iDim - 1 to 1 Step -1 If $iLoc[ $i ] = $iDims[ $i ] Then $iLoc[ $i - 1 ] += 1 $iLoc[ $i ] = 0 EndIf Next WEnd Return StringTrimRight($sRet,1) EndFunc Func _StringtoArrayMD( $sData, $sDelim="," ) Local $aData = StringSplit( $sData, $sDelim ) If @error then SetError( @error ) Return 0 EndIf Local $iDim = $aData[1], $iLoc[ $iDim ], $iDims[ $iDim ], $i, $counter Select Case $iDim = 0 Return $aData[ 2 ] Case $iDim = 1 Dim $aRet[ $aData[ 2 ] ] Case $iDim = 2 Dim $aRet[ $aData[ 2 ] ][ $aData[ 3 ] ] Case $iDim = 3 Dim $aRet[ $aData[ 2 ] ][ $aData[ 3 ] ][ $aData[ 4 ] ] Case $iDim = 4 Dim $aRet[ $aData[ 2 ] ][ $aData[ 3 ] ][ $aData[ 4 ] ][ $aData[ 5 ] ] Case Else MsgBox(0, "Error", $iDim ) EndSelect For $i=1 to $iDim $iDims[ $i - 1 ] = $aData[ $i + 1] $iLoc[ $i - 1 ] = 0 Next $counter = $iDim + 2 While $iLoc[0] < $iDims[0] Select Case $iDim = 1 $aRet[ $iLoc[ 0 ] ] = $aData[ $counter ] Case $iDim = 2 $aRet[ $iLoc[ 0 ] ][ $iLoc[ 1 ] ] = $aData[ $counter ] Case $iDim = 3 $aRet[ $iLoc[ 0 ] ][ $iLoc[ 1 ] ][ $iLoc[ 2 ] ] = $aData[ $counter ] Case $iDim = 4 $aRet[ $iLoc[ 0 ] ][ $iLoc[ 1 ] ][ $iLoc[ 2 ] ][ $iLoc[ 3 ] ] = $aData[ $counter ] EndSelect $counter += 1 $iLoc[ $iDim - 1 ] +=1 For $i = $iDim - 1 to 1 Step -1 If $iLoc[ $i ] = $iDims[ $i ] Then $iLoc[ $i - 1 ] += 1 $iLoc[ $i ] = 0 EndIf Next WEnd Return $aRet EndFunc Link to comment Share on other sites More sharing options...
erifash Posted July 26, 2005 Author Share Posted July 26, 2005 (edited) Aaaaahhh! Confusing! At least it does what it is supposed to do though. For that I am thankful.I have fixed what I wanted to do already though, but I am waiting for blindwig to make a function to convert a two-dimensional array back into a binary tree.Great job though, I am pleased. In case anyone wanted the code that I was trying to accomplish, here it is (so far):expandcollapse popup#include <MWR_BTree.au3> ;Create the Binary Tree $btUserDB = _BTreeCreate() While 1 $user = InputBox("Username Set", "") If @error Then ExitLoop $pass = InputBox("Password Set", "", "", "") If @error Then ExitLoop _BTreeSet($btUserDB, $user, $pass) Wend ;See how ugly your tree can be MsgBox(0,'MWR_BTree UDF Test: Raw Tree',_BTreePrintKeys($btUserDB)) ;See how pretty your tree can be _BTreeOptimize($btUserDB) MsgBox(0,'MWR_BTree UDF Test: Optimized Tree',_BTreePrintKeys($btUserDB)) _BTreeWriteINI($btUserDB, "DB.ini") $arr = _BTreeReadINI("DB.ini") ;============================== ; ;Convert $arr to a proper binary tree here ; ;============================== Func _BTreeWriteINI(ByRef $btTable, $sINI) Local $aArr = _BTreeToTable($btTable), $iDim = UBound($aArr, 1) - 1, $a, $b For $b = 0 to 2 For $a = 0 to $iDim INIWrite($sINI, $b, $a, $aArr[$a][$b]) Next Next INIWrite($sINI, "Dimensions", "dim", $iDim) EndFunc Func _BTreeReadINI($sINI) Local $aNames = INIReadSectionNames($sINI), $aSection, $a, $b, $aArray[INIRead($sINI, "Dimensions", "dim", "") + 1][4] For $b = 0 to 2 $aSection = INIReadSection($sINI, $aNames[$b + 1]) For $a = 0 to $aSection[0][0] - 1 $aArray[$a][$b] = $aSection[$a][1] Next Next Return $aArray EndFuncLink to Binary Tree topic: http://www.autoitscript.com/forum/index.php?showtopic=13114@blindwig: The dimensions alternate based on the ubound of that element, if that helps because I have no clue what I was trying to do. I really think writing to an INI works better. Edited July 26, 2005 by erifash My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver Link to comment Share on other sites More sharing options...
blindwig Posted July 27, 2005 Share Posted July 27, 2005 (edited) OK, go to my Binary Tree post and get the _BTreeFromArray functions. Then use this code: CODE #include <MWR_BTree.au3> ;Create the Binary Tree $btUserDB = _BTreeCreate() While 1 $user = InputBox("Username Set", "") If @error Then ExitLoop $pass = InputBox("Password Set", "", "", "") If @error Then ExitLoop _BTreeSet($btUserDB, $user, $pass) ;Optimize every once in a while If Mod($btUserDB, 50) = 0 Then _BTreeOptimize($btUserDB) Wend ;final optimization, if necessary If Mod($btUserDB, 50) <> 0 Then _BTreeOptimize($btUserDB) ;Show the final tree MsgBox(0,'User Tree (from memory)',_BTreePrintKeys($btUserDB)) ;write tree to file _BTreeWriteINI($btUserDB, "DB.ini") ;read tree from file $btUserDB = _BTreeReadINI("DB.ini") ;show the tree again (should be the same) MsgBox(0,'User Tree (from file)',_BTreePrintKeys($btUserDB)) Func _BTreeWriteINI(ByRef $btTable, $sINI) Local $tblUsers = _BTreeToTable($btTable), $i For $i = 1 To $tblUsers[0][0] INIWrite($sINI, 'Users', $tblUsers[$i][0], $tblUsers[$i][1]) Next EndFunc Func _BTreeReadINI($sINI) Local $aTemp = IniReadSection($sINI, 'Users') Return _BTreeFromArray2($aTemp) EndFunc Edited July 27, 2005 by blindwig My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions 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