Getting one row of data into variables then update to next row

I am very new to KM so I will apologize if this seems like a trivial question.

The problem I am trying to solve is taking 4-6 names of people(currently using a csv but if that is what's making this hard, I can use a different input method) and creating the maximum number of groups possible with a minimum of two in a group. Below is the example with 4 people.

image

I would like to store the first group into variables(in this case only two variables would have data), then perform some automation based on those two names, which I don't need help with, then clear all variables and store the next group until I have made it though all of the possible groups.

I have attempted to find a solution on the forums, but believe I may have so little understanding of how JSON works to make any progress on my own. Any input would be greatly appreciated.

Here is a macro to do it.

Basically, it iterates through the numbers from 1 to 2^Count-1 to get all the possible bit patterns. With each bit pattern, it clears out the variables and sets the variables to the value for any “1” bits. Then if there are at least two variables included, it does stuff - in this case it just logs all the variables.

Note that if you might use variables beyond the list count (eg variable Name5 for the example case), you'll need to clear them out to before starting this process.

Subsets.kmmacros (11 KB)

1 Like

FWIW you can access parts of a Keyboard Maestro variable with one-based indices between square brackets in this pattern:

yielding a result like:

token:JSONValue [Keyboard Maestro Wiki].)


Where the subsets here were derived by a generic function in a Keyboard Maestro Execute JavaScript for Automation action:

// subsets :: [a] -> [[a]]
const subsets = xs => {
    // The list of sublists of xs,
    // including the empty list.
    const go = ys =>
        0 < ys.length
            ? (() => {
                const
                    h = ys[0],
                    zs = go(ys.slice(1));

                return [
                    ...zs.map(z => [h, ...z]),
                    ...zs
                ];
            })()
            : [[]];

    return go(xs);
};

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

    const main = () => {
        const
            kmv = kmValue(kmInstance()),

            xs = kmv("local_values")
            .split(",")
            .map(s => s.trim()),

            m = kmv("local_minimumSetSize"),
            n = isNaN(m)
                ? Number.NEGATIVE_INFINITY
                : Number(m);

        return JSON.stringify(
            subsets(xs)
            .filter(ys => n <= ys.length)
        );
    };

    // --------------------- GENERIC ---------------------

    // subsets :: [a] -> [[a]]
    const subsets = xs => {
    // The list of sublists of xs,
    // including the empty list.
        const go = ys =>
            0 < ys.length
                ? (() => {
                    const
                        h = ys[0],
                        zs = go(ys.slice(1));

                    return [
                        ...zs.map(z => [h, ...z]),
                        ...zs
                    ];
                })()
                : [[]];

        return go(xs);
    };

    // ---------------- KEYBOARD MAESTRO -----------------

    // kmInstance :: () -> IO String
    const kmInstance = () =>
        ObjC.unwrap(
            $.NSProcessInfo.processInfo.environment
            .objectForKey("KMINSTANCE")
        ) || "";


    // kmValue :: KM Instance -> String -> IO String
    const kmValue = instance =>
        k => Application("Keyboard Maestro Engine")
        .getvariable(k, {instance});


    // MAIN ---
    return main();
})();

As in something like:

3 Likes

Thank you both for the help. This made it much easier to understand.

2 Likes