Jump to content

AutoIT nested dictionary - print using recursion


 Share

Recommended Posts

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

?

$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

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

 

Link to comment
Share on other sites

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 by AspirinJunkie
deleted attachment, because there is an extra thread for this udf
Link to comment
Share on other sites

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 by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...