Jump to content

Recommended Posts

Posted

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!

Posted

?

$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

 

Posted

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

 

Posted (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 by AspirinJunkie
deleted attachment, because there is an extra thread for this udf
Posted (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 by iamtheky

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

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
  • Recently Browsing   0 members

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