How to Sort JSON Dictionary Entries Alphabetically

Howdy folks, I have a question that is perhaps not directly related to Keyboard Maestro but I imagine somebody here will know the answer either way.

I have been using iOS/iPadOS Shortcuts app in conjunction with a Keyboard Maestro macro to run macros from my iPhone/iPad. I can't for the life of me remember who here provided it; I wish I did because it works GREAT. Either way, it works in the following way:

  1. Shortcuts app reads a json dictionary in my Dropbox folder which contains my macro UUIDs
  2. It then allows me to select an entry from that dictionary
  3. The entry's UUID is then saved to a txt file which is put into a folder the KM monitors.
  4. When the file is synced, KM reads its contents (the macro UUID), and then uses an AppleScript to execute that macro.
  5. The file is then deleted.

All of that works perfectly fine. But what I've noticed is that when Shortcuts reads the json file, the order that the list appears in is, if not random, then at least not in the order that appears in the file itself. For example, here is how I have the text sorted in the json file:

{
	"LB work apps open" : "538205B6-CF94-4046-BB0A-0F16BA9FE3AA" ,
	"LB work apps close" : "5FB905C1-6426-4A1B-8647-2678AB790AAD" ,
	"LB status check" : "D55B80E5-BC88-4468-AA6F-A29B3EC62F78" ,
	"LB status set to away" : "1FFBC635-4476-46CD-854C-35F03403B8B0" ,
	"LB status set to available" : "FD70B76B-29EC-447E-9B08-8B1D1ADA1EE1" ,
	"Toggle microphone (MicDrop)" : "C6EB8B41-7735-4347-8A38-D8BD48EED37E" ,
	"Toggle microphone (MuteMe)" : "98228A5C-34F3-4120-A699-15EE46052168" ,
}

And the screenshot shows how it appears when run from my iPhone/iPad:

I can't seem to see any rhyme or reason why it's in that order since it doesn’t appear to be sorted by name, UUID, or even which one was triggered last. So what I'd like to do is see if there's a way to have the list appear in the same order it has in the json file when ran from Shortcuts.

Here is a link and screenshot of the Shortcuts shortcut, as well as the KM macro if anybody wants to see it.

Shortcuts link:
https://www.icloud.com/shortcuts/7027497ea82148c58b083bc76a5e1c7e

Shortcuts screenshot:

Keyboard Maestro macro
49)iOS Shortcuts Macro Trigger.kmmacros (30 KB)

Sorry for the wall of text, but I figure the more info the better. Any info/advice is appreciated. Thanks in advance!

-Chris

A first broad observation is that the specifications of JS Object keys and their JSON representation essentially leaves their sort order undefined.

You can often get them into a sorted order with a controlled creation process, but nothing in the standards strongly protects the preservation of that order, or even defines them as sorted values. (Some later versions of the ECMAScript standards have moved towards a degree of order preservation in iterations, but you have to know which interpreter you are dealing with, so its grayish).

If you really want a persistently sorted set of keys then you may need to

  • keep the sorted keys in a separate array, starting with a call to Object.keys(...) to harvest the keys for sorting, and then
  • refer to that array (or iterate over that array) for the order, rather depending on the dictionary key collection directly.

According to ECMA-404 The JSON Data Interchange Standard.

" An object is an unordered set of name/value pairs."


Which will tend to mean that even if you are using a JS version which tries to preserve the order of keys in a live Object, nothing guarantees that preservation in serialization to, or parsing from, a JSON string representation.

Array order, however, will always be preserved, both in live JS Array Objects, and in the writing and parsing of JSON strings.

EDIT: Never mind. I'm an idiot.

I'm probably not understanding what you have in mind there.

(No JSON parser or JS interpreter can parse the pattern that you seem to be showing ...)

Thwap! (That's the sound of my hand hitting my forehead). You're right, of course. And if I code it correctly, it's unlikely that it can be used that way.

Sigh.

The short answer to the question in the thread title is "You don't." Dictionaries are stored internally in a way that makes for fast lookup and insertion—order is not maintained. (Some languages have ordered dictionaries, but Shortcuts isn't one of them.)

@ComplexPoint outlined the standard solution to this problem:

  1. Extract the keys of the dictionary and put them in a list.
  2. Sort that list of keys.
  3. Ask the user to choose from the (sorted) list of keys.
  4. Look up the UUID from the chosen key.

Unfortunately, Shortcuts, as far as I can tell, has no way to do Step 1, which is a terrible deficiency of the language. But I think you can use Scriptable within Shortcuts to extract the keys (see @ComplexPoint's first post), sort them, and use that in a Choose from List step.

Sadly, I am long out of practice with Scriptable and was never very adept with it in the first place, so I can't be any more specific than what I've just said.

I think that this is what you are after:

1: Alphabetic Sort of Dictionary

2: Sort to original dictionary order

3: Sort to dictionary order using Toolbox Pro (i*OS only)

The first Shortcut will sort the dictionary keys into alphabetical order no matter what order they are entered in the dictionary, using the Files action to perform the sort.

Version 2 will sort the list of dictionary items into the order that they appear in the dictionary. This requires that the dictionary keys have an order added to the front of the key (in my example 1, 2, 3), which is then removed by a regex replace after the sort but before the list is displayed. The prefix would need to be re-added to the selected option before the dictionary lookup of the selected item was performed.

Version 3 is the same as version 2, but uses the i*OS app Toolbox Pro (free version of the app, but there is not a macOS version so only added for completeness) to perform the sort as sorting via the Files command seems a little strange...

The removal and replacing of the lead number for the sort can obviously be ditched if you are happy to have a "1,2,3" at the start of your dictionary keys and display that in the list displayed for selection.

Hope this helps.

1 Like

This version of the Shortcut also has a sample of how to re-add the index to the start of the option selected so that it can be used in the dictionary lookup.

Hope this helps.

Holy cow thanks everybody for all the detailed information. Pretty much all of it is way over my head, so it's gonna take me quite a while to sort through it and see if I'm able to use it.

Even if it's beyond my skills now, I'm gonna squirrel it away for the future when hopefully I'll be more knowledgeable.

Thanks again!

-Chris