Nested dicts (to write and to query, that is the question)
So I've been dict-ing it on up, all over the place in my patch(es), and there are a couple of things that seem a bit weird to me, so I suspect there are easier ways to do this.
The first one is that I want to write nested dicts, but with arbitrary names, or more specifically, arbitrary amounts. I'm using [counter] to generate keys and creating lots of nested dicts, all with different contents/settings.
A structure like this:
{
"1" : {
"some" : "one",
"thing" : "two",
"else" : "three"
}
}
As much as possible I've been using the dict.objects, so I'm using dict.pack at the top leve to generate what will become the nested dict, but then in order to create a dynamic nested dict name, dict.pack doesn't appear to work. So I'm using a [prepend] with a [set append $1] going in to it. This works, but feels like an awful workaround. (labelled/clear example of this in the code quoted below)
Is there a better (native dict.object) way of adding nested dicts with arbitrary/names without explicitely named [dict.pack insert_name_here:] objects?
SECONDly, once I have a nested dict structure set up, is there a simple way of querying for a specific 'value' at a certain hierarchy depth?
For example, if I have a dict that looks like this:
{
"first" : {
"some" : 1,
"thing" : 6,
"else" : 3
}
,
"second" : {
"some" : 8,
"thing" : 5,
"else" : 2
}
,
"third" : {
"some" : 7,
"thing" : 4,
"else" : "9
}
}
How do I specifically query for the value '8' for example? Now I can 'getkeys', then use that to cycle through the keys, then use that to cycle through the keys etc... Now this works, but it's suuuper clunky, not to mention if I want to query through a dict for all the values to figure out the order of them, I have to loop through the whole process looking for each key specifically (like sorting algorithm style).
Is there a way to query for a specific value through arbitrary nested keys (so can't "get first::some").
p.s. this thread was super useful, as was this blog post.
Obviously dict has cons and pros. So for complex and flexible data management I'm often using a combination of dicts and colls (including temporary conversions between them).
I'm doing something similar, particularly when it comes to large data sets, as [dict.iter] is SIGNIFICANTLY slower than 'dump'-ing a coll. But the main issue here is that I want to be able to easily pattrize/recall dicts inside a M4L device.
That being said, I did find a workaround for the [prepend append] problem.
If you use a @named dict.pack (i.e. [dict.pack @name ---CurrentlyLoadedCorpora]), then you can send it a message of 'keys whatever' and it works fine. If you do the same without the @name attribute, then it generates a generic foo::bar key/value pair, which is annoying.
yeah i have been burned by that @named only working on dict.pack if explicitly declared first. it must be a bug. i have lazily not reported that one, sorry. once done though, it solves all your issues, no? i use it to dynamically name nested dicts when structure is not known beforehand. i guess improving dict.iter / dumping would be very high on all our future request lists for max 8 :-)
Actually as I dicovered, the @name thing still does create a generic "foo:bar" entry, but only sometimes (possibly bug?). Specifically in my patch I noticed that the named [dict.pack @name histogram] works just fine, creating an empty dictionary on startup, but having two [dict.pack @name analysis] creates a foo:bar entry on startup. Took me a while to troubleshoot/find that as deleting just one didn't solve it, and the [dict.pack]s arent receiving any messaging on loadup.
You would presume that the dict.objects would take messages ala pack/join/group/etc...
On a real positive note, I've managed to totally get all the dict stuff I want working! (including recalling/reloading all data when the patch is loaded) There are lots of workaround all over the place, given the kind of things I want to do with dicts, but it's working!