Jonjilla
Jonjilla

Reputation: 463

getting nested keys from tcl dict

If I have a nested dict in Tcl like so

dict set mydict1 A key1 value1
dict set mydict1 B key1 value1
dict set mydict1 B key2 value2
dict set mydict1 C key3 value3

I'd like to identify the list of all of the second level keys in this dictionary. IN this case, I would like to know that the second level keys are key1,key2,key3

Is there a way to get this list of values from this dictionary directly?

Upvotes: 0

Views: 1791

Answers (2)

user4318224
user4318224

Reputation:

Thanks to Donal I was able to further refine the solution to the following (which requires tcl >= 8.6 for the lmap):

lsort -unique [concat {*}[lmap k1 [dict keys $mydict1] {dict keys [dict get $mydict1 $k1]}]]

Upvotes: 0

Donal Fellows
Donal Fellows

Reputation: 137717

There's no built-in command for doing this, nor even a way for the code to know on your behalf that that's what the structure is (which is a consequence of the type system in Tcl). However, if you know that there's definitely always two levels though, it's not too hard to code it yourself.

proc two-level-enumerate {dict} {
    set keypairs {}
    dict for {key1 subdict} $dict {
        foreach key2 [dict keys $subdict] {
            lappend keypairs [list $key1 $key2]
            ### Depending on what you're doing, you might prefer:
            # lappend keypairs $key1 $key2
        }
    }
    return $keypairs
}

The tricky bit for the generic Tcl layer is knowing that there's two levels, as it can't safely use the internal types on values (the types of literals are quite tricky, and on the flip side, determining the intended structure vs what you've happened to put in beneath it is also awkward). Being explicit — the code above — works much better.

Upvotes: 1

Related Questions