Finally! A Way to Extract JSON Key Names - yourJsonString.ParseJSON("$.*~")

Hi Coda Makers! :waving_hand:
(especially those of you working with JSON in Coda - @Math_24, @Agile_Dynamics, @Eric_Koleda, @Scott_Collier-Weir, @Paul_Danyliuk)

I don’t know about you, but I have been looking for a solution to this for years - trying to find a way to extract the names of keys from JSON objects (not just their values). ParseJSON() works great for extracting values form JSON when you know the key name. But how do you extract the key name?

I finally found a solution!

It turns out that Coda’s ParseJSON() function supports a special JSONPath syntax that isn’t documented anywhere - not in Coda’s formula reference nor in the original JSONPath specification by Stefan Goessner! I’ve searched through all forum posts about JSON and haven’t seen anyone mention this technique before.

The Hidden ~ Operator in ParseJSON()

ParseJSON(yourJsonString, "$.*~")

The tilde (~) character tells JSONPath to return the key names instead of the values! This appears to be a Coda-specific extension to JSONPath or perhaps from a later JSONPath implementation they adopted.

Patterns:

  • $.*~ - All top-level keys
  • $..~ - All keys at any level (recursive)
  • $.objectName.*~ - Keys in a specific nested object
  • $.[*].*~ - Keys in top-level array items

Examples:

For a simple JSON object:

{
  "name": "Bob", 
  "age": 42, 
  "address": {
    "street": "123 Main St",
    "city": "Springfield"
  }
}
  • ParseJSON(jsonString, "$.*~") returns ["name", "age", "address"] (top-level keys)
  • ParseJSON(jsonString, "$..~") returns ["name", "age", "address", "street", "city"] (all keys at any level)
  • ParseJSON(jsonString, "$.address.*~") returns ["street", "city"] (keys in the address object)

Why This Matters

This solves so many problems that the community has been tackling with workarounds:

  1. @Agile_Dynamics was looking for dictionary-like functionality in the “How to create a ‘dictionary’ object?” thread, and tried using the hidden _Deref_Object() function.

  2. @Paul_Danyliuk mentioned that there was “no ‘legal’ way to extract a name by value yet” when discussing Object() and suggested using hidden, unsupported functions.

  3. In “Unexpected non-whitespace character after JSON”, users were struggling with JSON formatting but couldn’t easily inspect the structure.

  4. @Ratish_Gupta and others have been using the now “sunsetted” _DEREF function for complex data operations as mentioned in “Formula Map Sequence + DEREF”.

15 Likes

Oh that’s awesome, thank you for this :clap:

2 Likes

Nice! How did you find this, given that it’s not in the spec?

2 Likes

I was actually working on a non-Coda project when I came across jsonpath-plus and wondered if maybe any of these operators would work in ParseJSON() (or even if maybe this is what Coda uses under the hood).

I’ve built several packs that involve manipulating JSON, so a significant part of my brainpower :brain::battery: at any given moment is devoted to thinking up solutions to retrieving JSON Key Names in Coda. I work a lot with arbitrary, LLM-generated JSON.

So on a whim I tried $.*~ and it worked!

p.s.

As it turns out, after running some tests, I don’t actually think that Coda uses the jsonpath-plus library, under the hood - not per se. As far as I can tell, ParseJSON() supports some jsonpath-plus commands, but not all. So my guess is that the codans were partially inspired by jsonpath-plus as they built and iterated on ParseJSON().

(I can’t confirm this, but I believe that the original Coda ParseJSON() implementation was very limited, and that it’s been improved over the years.)

6 Likes