I’m trying to learn how to make custom dictionaries work, as they seem to really help simplify workflows when done correctly. I have a sample shortcut here that attempts to take a set of text, split the text, assign each text segment to become a dictionary value, and then use that dictionary to create a table. I’m clearly doing something wrong, but as I’m still learning about dictionaries, I’m not sure what. Is it even possible to create a dictionary in this way? Any ideas?
To build one from text, the best way is probably to express it as JSON and then use the get dictionary from input action. After that, you can enumerate the keys and iterate over them in a repeat loop.
But unless you want to pick out specific values by name, the above could in effect be achieved just by using a list and the split approach you began with.
Hope that helps.
You don’t need to pre-build the dictionary items. If a key does not exists in the dictionary,
Set Dictionary Value will create it for you.
True, you don’t have to pre-build the items, but I’m struggling to see the practical benefit of doing this.
To me it seems like there is less overhead for creation, and at worst, an equivalent in access, to simply splitting into a list and then referencing the item by index. i.e. I see no imperative to coerce the data into a dictionary over an originating list, if it is an index based list to begin with.
It’s quite possible I’m overlooking a key scenario. Is there one, … or more where this would be a key approach?
The only thing I can think of so far is if this was specifically a data transform for inclusion of a sub-set of data in a larger dictionary and it was already available as a separated text string. But that’s quite specific.
After a quick test, just in case, I don’t think there’s a performance benefit in Shortcuts using a dictionary vs. an index references either.
I don’t think there is a benifit for performance but you can cut down on work and add privacy which are my two reasons for a dictionary over a list referenced via index (and a third for whatever I find simpler).
If you use dictionaries you can share a shortcut and then strip out sensitive data while keeping the dictionary variables in place then have the super fill in the data with import questions.
Also if your going to use common variables across multiple shortcuts (ie a shortcut to say access redditt that you could use the run in shortcut option to treat them as dependencies.
Or it can just “feel” neater to reference one big dictionary throughout a shortcut rather than getting and references various lines of a larger list.
In the end I think it’s prefrence. More and more I am using dictionaries but there are plenty of times a mess of variables or a indexed list works just as quickly
This kind of problem definitely lends itself to a list. You can take the lines of text and run them through a single “Join Text” action with a custom
| delimiter, then bracket that in
| for your table output. See this example
I agree with your points above, though they appear to be regarding other use cases. I don’t believe they apply to the sort of example above, for converting text into a dictionary with indexed identifiers which is what my query specifically pertained to.
@jasonact, did it ever work for you?
I have a similar use case that I thought would work right away, but it didn’t (kept getting the below conversion error at the “set dictionary” step).
After few Hours of banging my head against the phone, I Stumbled upon your post and realized this wasn’t probably not supported yet in shortcuts version 3.2 (iOS13.3.1).
However, apple site https://support.apple.com/guide/shortcuts/dictionaries-apd43b69f337/ios suggests it should be, per the very first bullet (pasted below):
Use dictionaries in the following ways:
- Enter text, numbers, values, dictionaries, or lists into a Dictionary action to manually create a dictionary for use in your shortcuts.
I did try few additional things to see if lack of JSON formatting was an issue,. enclose each index and item with inverted commas (“) and then
using them as text type magic variables in set dictionary …it didn’t work/same error
using them as key and value types respectively in the set dictionary…it didn’t work/same error
Don’t see the point of creating a list of dictionary manually for each of those items. In fact, it would be tricky since I am fetching those values from a different website.
It looks like you are trying to do what @supermamon posted above - convert a new line list of text into a dictionary keyed on the position of the line in the text. Did you try it like that, or have I misunderstood and you are trying to do something different?
@sylumer, thanks for your quick reply. Here is what I have
“Show Alert” works fine and shows One line - Meli H 505,000 5
However, the “set key to value in dictionary” fails with conversion error.
Rather than screenshots, it can be helpful to post the actual shortcut to debug, particularly when you have long URLs, RegEx, and other things that could be easily mistyped if someone ends up having to manually recreate a shortcut; which they are unlikely to do when it is so easy for people to share them.
Looking at your screenshot, I see this at the end:
You are adding your key value pairs to what dictionary? It looks blank to me, as though you have missed it out. I don’t see any dictionaries defined earlier either.
Try adding a dictionary action somewhere prior to your loop and then referencing that in your Set action to specify adding them to that dictionary, and then update the dictionary from the one the set action generates.
Here’s an example shortcut:
In case it is quicker to just view the differences in this instancr, here’s a screenshot.
@sylumer, specifying the directory name indeed solved it. See here.
I am working on nested directories now, but it hasn’t been working. Will post the entire shortcut in a bit.
Two quick questions mean while -
Q - in your example shortcut, why waa the “set variable colors to dictionary” needed inside the repeat loop, given the previous statement “set repeat index to repeat value in colors” should already be doing it?
Q - would it be futile to define the directory structure (with specific key names) in the beginning, given that repeat loop is being used with index later on to update the directory?
That’s easily checked by removing it.
If you look at the documentation for the Set Dictionary Value action you can note that it has an output.
This differs to what Set Variable has, which is what you are most likely comparing against.
Whenever I have used it I have had to in effect overwrite the referenced dictionary with the updated dictionary generated by the action.
- If the data being created can vary and you need some defaults it would be necessary to ensure those values always exist at the end regardless of the values being added on a particular occasion.
- If you want a reference to validate against (an internal documentation of the data), then it could be useful to prepopulate, assuming this is not easily read elsewhere in the shortcut.
- If the build is constant in terms of the keys generated, no additional defaults are required, and the generation source is a simple listing within the Shortcut, then there is no benefit to prepopulation of the dictionary.
I think I actually found a different way to do what I wanted, but I don’t remember what that was. In any case, I kind of moved on from this question. Thanks.
Thanks @sylumer. So, I ended up creating a nested dictionary (with a list, though I had initially a dictionary, but it didn’t work) to store score and rank with each name and finding it not working. Two issues really -
First, each item in each line in the repeat loop is taken as text type, even though the item is a number. That breaks the logic for matching.
Second, iterating doesn’t help saving the item2 in the nested dictionary. I have tried a dictionary with dictionary and dictionary with list, but no luck.
Third issue, second split by space not working, got resolved as soon as I put the if clause (for first 5 lines) after the first match.
You can tap on the type and change it.
If you are treating something as a nested variable, try building that variable first and then adding that variable to the original.
That would be down to the source data. Use one or more Quick Look actions in the problem area of your shortcut to take a look at why that would be. Use them to step through and examine the data. I’d start back at the new line matches.
First issue, while the type can be changed, it wouldn’t help since it would require one to know exactly the type for each repeat element a priori.
Second issue, do you have an example?
Third issue, what fixed it was a surprising usage of an if clause. I will check if the issue comes back without the repeat loop, which would indicate 2nd split in a row having a big.
You always need to have a handle on your data types. You have to use a consistent data type to do direct content comparisons on repeating items in every programming structure/language I’ve ever used. If that wouldn’t work for you for some reason, then you should look at transforming your data set to one where you can do this.
In terms of an example for building nested dictionaries such as a list or dictionary within another dictionary, I don’t have one to hand. But if you create and populate a dictionary XD, you could then add that as say a keyed value XD in dictionary YD. To iterate over dictionary XD later, access the XD element of dictionary YD, enumerate the keys of that dictionary and iterate over them.
I still think you can use the approach I suggested to help you understand what is going on better with your if-based line skipping.
I have the Nested dictionary almost working, just that the dictionary output Isn’t pretty for some reason. It prints backsplash (/) after every key and value. See below -
This only happens after getting out of the first repeat loop, but not inside. The shortcut program is here -
The example listed here helped with nested dictionary initially, but this program doesn’t exhibit such “/“ printing
Take a look at this tweaked version.
You are taking a JSON format text (containing double quotes), and setting it to the value of the top level element in the dictionary. Placing this into a text element means that the app has to escape those double quotes.
I think you probably wanted to pass it on as a dictionary. Like this:
I’m guessing that your “saving” logic is a work in progress and that the final operation probably wouldn’t be messaging a JSON string.
Hope that helps.