Renderer Posted January 11, 2021 Share Posted January 11, 2021 Hi Guys! I have a small problem regarding nested dictionaries in AutoIT and recursion. Let's consider the following nested dictionary: dictionary = { "Key1": "Value1", "Key2": { "Sub-Key", "Sub-Item", "Sub-Key-2": { "Sub-Sub-Key": "Sub-Sub-Item" } } } Translated into AutoIT code it would be: $dict = ObjCreate("Scripting.Dictionary") $dict.Add("Key1", "Value1") $dict.Add("Key2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Add("Sub-Key", "Sub-Item") $dict.Item("Key2").Add("Sub-Key-2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Item("Sub-Key-2").Add("Sub-Sub-Key", "Sub-Sub-Item") I am trying to print this dictionary to console using recursion. I do not know how to apply it correctly. Here's an example: func KeyHasSubKeys($dict, $key) return (Ubound($dict.Item($key).Items) > 0) endfunc ;Check Key for Subkeys func PrintDict($dict) for $key in $dict if not KeyHasSubKeys($dict, $key) then ConsoleWrite($key & ":" $dict.Item($key) & @crlf) else for $SubKey in $dict.Item($key) ; ... this is were I get stuck next endif endfunc Can anyone help me solve this problem? The final output in console shoult be like the nested dictionary I posted above in plaintext. I think this problem can be solved using recursion, becuase it's about finding out if a key has subkeys ans so one. I am new to recursion in programming, so I cannot apply it correctly. Thanks in advance! Link to comment Share on other sites More sharing options...
mikell Posted January 11, 2021 Share Posted January 11, 2021 ? $dict = ObjCreate("Scripting.Dictionary") $dict.Add("Key1", "Value1") $dict.Add("Key2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Add("Sub-Key", "Sub-Item") $dict.Item("Key2").Add("Sub-Key-2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Item("Sub-Key-2").Add("Sub-Sub-Key1", "Sub-Sub-Item1") $dict.Item("Key2").Item("Sub-Key-2").Add("Sub-Sub-Key2", "Sub-Sub-Item2") $dict.Add("Key3", "Value3") PrintDict($dict) func KeyHasSubKeys($dict, $key) return IsObj($dict.Item($key)) endfunc ;Check Key for Subkeys func PrintDict($dict) for $key in $dict if not KeyHasSubKeys($dict, $key) then ConsoleWrite($key & ":" & $dict.Item($key) & @crlf) else ConsoleWrite($key & ":" & @crlf) PrintDict($dict.Item($key)) endif next endfunc Link to comment Share on other sites More sharing options...
Nine Posted January 11, 2021 Share Posted January 11, 2021 Another way with index : #include <String.au3> $dict = ObjCreate("Scripting.Dictionary") $dict.Add("Key10", "Value1") $dict.Add("Key11", "Value2") $dict.Add("Key2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Add("Sub-Key0", "Sub-Item1") $dict.Item("Key2").Add("Sub-Key-2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Item("Sub-Key-2").Add("Sub-Sub-Key", "Sub-Sub-Item") $dict.Item("Key2").Add("Sub-Key1", "Sub-Item2") $dict.Add("Key3", "Value3") ConsoleWrite ("dictionnary = {" & @CRLF) PrintDict($dict, 1) Func PrintDict ($oDic, $lvl) For $i = 0 to $oDic.count - 1 If IsObj($oDic.items[$i]) Then ConsoleWrite (_StringRepeat(@TAB, $lvl) & $oDic.keys[$i] & ": {" & @CRLF) PrintDict($odic.items[$i], $lvl+1) Else ConsoleWrite (_StringRepeat(@TAB, $lvl) & $oDic.keys[$i] & ": " & $oDic.items[$i] & @CRLF) EndIf Next ConsoleWrite (_StringRepeat(@TAB, $lvl-1) & "}" & @CRLF) EndFunc “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
AspirinJunkie Posted January 11, 2021 Share Posted January 11, 2021 (edited) This is crying out for JSON. The easiest way is to use one of the UDFs that supports serialisation. Example with the UDF from the appendix: #include <JSON.au3> $dict = ObjCreate("Scripting.Dictionary") $dict.Add("Key10", "Value1") $dict.Add("Key11", "Value2") $dict.Add("Key2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Add("Sub-Key0", "Sub-Item1") $dict.Item("Key2").Add("Sub-Key-2", ObjCreate("Scripting.Dictionary")) $dict.Item("Key2").Item("Sub-Key-2").Add("Sub-Sub-Key", "Sub-Sub-Item") $dict.Item("Key2").Add("Sub-Key1", "Sub-Item2") $dict.Add("Key3", "Value3") $sSerialized = _JSON_Generate($dict) ConsoleWrite($sSerialized) Edited April 9, 2023 by AspirinJunkie deleted attachment, because there is an extra thread for this udf Link to comment Share on other sites More sharing options...
iamtheky Posted January 11, 2021 Share Posted January 11, 2021 (edited) calling them back the way trancexx suggested in the above thread is the only way dictionary in dictionary ever really played nice for me (the add keyvaluepair function is just a wrapped add). Edited January 11, 2021 by iamtheky ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) 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