JSON: Find Object Based on Non-Key Value

Apologies in advance if I get some terminology wrong. Just starting to discover the power of using JSON :wink:

Imagine I have a JSON dictionary like this:
{ "id" : 1, "text1" : "pizza" },
{ "id" : 2, "text1" : "spinach" }

If I wanted to find out the ID of a JSON object where “text1” is “spinach”, I could do that either by using a “for” loop to check every object individually, OR I could use a “search” action with a regex pattern to find it.

Is there an easier way to do this? I'm imagining some syntax like %JSONValue%.dictName.text1[spinach]% or something but couldn’t find anything in the documentation. I'm not familiar enough with JSON to know whether this is a normal thing to be able to do in programming or if one of my other options mentioned above is a normal approach.

Am I best to stick to my For loops or regex searching, or is there a more efficient and straightforward approach I could try?

Thanks in advance!

Joel

A little bit hard to imagine – that's two different JSON dictionaries, and the relationship between them is not very clear.

Are they successive items in a JSON array ?

e.g.

[
    {
        "id": 1,
        "text1": "pizza"
    },
    {
        "id": 2,
        "text1": "spinach"
    }
]

Could you:

  1. zoom out a bit to describe what you are trying to achieve, and
  2. post a draft macro containing some sample JSON ?

Thanks for the response and sorry for the unclarity. That’s what I meant to say, yes - successive items in a json array.

I’m just on my phone away from Mac but didn’t want to leave you hanging so I hope this clarification is sufficient without a macro example.

This scenario has come up several times in several different macros. At the moment, I’m trying to find and merge duplicate records from a custom table exported from a wordpress sql database. The table contains Portuguese vocabulary words exported as JSON, and I’m trying to find entries where the main Portuguese phrase (eg. Text1) is identical across multiple records.

So to start with, I loop through the json objects from that database table export, then I want to find if the current “text1” value is also found in another json object (database record). Using Regex to search the entire json file is the best way I’ve found so far, but i thought maybe there was another way to do it using magical JSON powers :slight_smile:

Is that any clearer or should I try to make an example macro when I’m back at Mac?

Thanks again for your time and help!

Joel

I would personally tend to do that with .findIndex in a KM Execute JavaScript for Automation action, but others may be able to show you alternative approaches.

(() => {
    "use strict";

    const k = "spinach";
    const xs = [{
            "id": 71,
            "text1": "pizza"
        },
        {
            "id": 72,
            "text1": "spinach"
        },
        {
            "id": 73,
            "text1": "hummus"
        }
    ];

    const
        indexFound = xs.findIndex(
            x => k === x.text1
        );

    return -1 !== indexFound ? (
        xs[indexFound].id
    ) : `Item with text1===${k} not found.`;
})();

Wowww this beautiful, a whole area of automation I still have to explore, but now I can see that it will be very helpful for making macros more efficient and simpler to create. Thanks again for your time, this is an excellent answer!

For example (using JSON.parse to obtain a live JS object or array from a JSON string)

Reading and searching a JSON array.kmmacros (2.2 KB)

Expand disclosure triangle to view JS Source
(() => {
    "use strict";

    const k = "spinach";
    const xs = JSON.parse(
        Application("Keyboard Maestro Engine")
        .getvariable("jsonSample")
    );

    const
        indexFound = xs.findIndex(
            x => k === x.text1
        );

    return -1 !== indexFound ? (
        xs[indexFound].id
    ) : `Item with text1===${k} not found.`;
})();

Thanks again for all your time on this. I know some javascript and a bit of other languages but get a bit lost with some of the more advanced skills being used here that I’ll have to Google to learn more about. But the beautiful thing about KM is that you can always just use useful snippets like this and over time fill in your gaps of knowledge little by little.

And this forum and the generosity of the community is one of the best parts of using KM.