I have a dictionary with 3 key value pairs. How do I find out the size? in this 3?
I could increment a counter but it seems tacky.
Ben
I have a dictionary with 3 key value pairs. How do I find out the size? in this 3?
I could increment a counter but it seems tacky.
Ben
Do you mean the total of the three Dictionary entries, assuming all three entires are numbers?
In which case a For Each
Action can do it.
I suppose a For Each
Action is a kind of counter but it's pretty concise. The two Green colored Actions are the ones that are doing the adding up of the values.
The single line of code to allow each Dictionary value to be added to the sum is:
LOCAL__Total + CALCULATE(%Dictionary[DCT__TempTest,%Variable%LOCAL__Key%]%)
Where DCT__TempTest is a placeholder for whatever your dictionary is called.
Don't worry about the red colored numbers - that's just because the code doesn't work until the Macro is run each time.
Oh, and because the For Each
Action simply goes through all the keys of the dictionary (no more and no less) the coding in the green Actions will work no matter how many keys you have. I set 3 entries at the start, because your example was 3. But it could be 19, 100 or whatever number of keys the Dictionary has. In that way it is different to an incrementing counter.
Another way to do this is to simply create a key in the dictionary, let's call it "Quantity", which you initialize to zero and add one to it whenever you create a new dictionary key. It's more work and more error-prone, but if I needed such a count, I would certainly consider it. I guess it depends on how often you need to obtain this number and how often the dictionary changes.
In manual:Dictionaries [Keyboard Maestro Wiki] you will see see examples of reading dictionaries with osascript
(AppleScript and JavaScript for Automation)
in AppleScript, given a KM Dictionary with the name "Avian", for example, you might write:
set dictName to "avian"
tell application "Keyboard Maestro Engine"
length of ((dictionary keys of dictionary dictName) as list)
end tell
or in JavaScript for Automation:
Application("Keyboard Maestro Engine")
.dictionaries.byName("Avian")
.dictionaryKeys()
.length
That is informative and insightful. However I don't see this info on the wiki on the page you cited. Could it be added?
Yep that can work for Dictionaries with a static name.
eg. Avian but mine are like Avian1, Avian2, Avian3 and I use an if "starts with contain" eg. Avian(n) to loop through the dictionary.
I could have done a regex to the number on the end eg. Avian3 but then what If I deleted a key value pair. Perhaps im doing it wrong.
Perhaps it should have been Dictionary as a fixed name and then Keys as a dynamic.
eg. Dictionary: Avian, Key: Code1, Code2, Code3 etc.
Anyways, how would I change that Execute Javascript for Automation to fit with my Avian1 and so on.
Ben
If we adapt the script a little, then:
Ohhh. when you said you wanted "the size of the dictionary" I thought you meant "the number of entires."
Some days I misinterpret the question. Sorry.
Even so, if you manually keep track of the size as you add and delete entries, and store that value in one of the dictionary's keys, that would work and would be the fastest solution. I wouldn't hesitate to do that.
How do I respond back to this post with a macro and its snapshot?
Sorry that there seems to be a lot of intervening noise
You can include the name of the poster, e.g. @complexpoint
How can we help you with that sketch of a macro ? If you have a working macro of your own which you would like to share here, we could integrate the mapping of dictionary names to key counts.
So ive used your code but I have to loop through the dictionary twice. First time to get the size, Second time to know when to append or not append | to the end of the string so that It could be separated inside a combobox.
Is there a better way to make it more concise, Tacky with two for each loops
Could you give us a single sentence to summarise the context of your macro, and what you need it to do within that context ?
In the meanwhile, one more general approach is to:
%JSONValue%
token as a way of extracting the key-counts that you want, whenever you want.e.g. something like:
All dictionary sizes.kmmacros (2.4 KB)
Incidentally a fractionally more efficient version of the script (more cacheing), would be:
(() => {
"use strict";
const
kme = Application("Keyboard Maestro Engine"),
dictionaries = kme.dictionaries,
byName = k => dictionaries.byName(k);
return JSON.stringify(
dictionaries.name().reduce(
(a, k) => Object.assign(
a, {
[k]: byName(k).dictionaryKeys.length
}
), {}
), null, 2
);
})();
the point of the macro is to build up multiple dictionaries or json objects and navigate them in input boxes to get where I needed to get to. eg. Accessing one dictionary value might point to another dictionary and the process repeats.
Ben