Search code examples
variablespipelinejq

Use a jq range variable to feed into a new jq filter


I have some JSON that looks like this:

{
    "vertices": [
        {
         "id": 71597,
          "ns": "ca",
          "alias": "polarized"
        },
        {
          "id": 129748,
          "ns": "av",
          "name": "Polarized"
        },
        {
          "id": 129898,
          "ns": "av",
          "name": "False"
        }
    ],
    "edgeGroups": {
        "hasAttributeValue": [
            [
              0,
              1
            ],
            [
              0,
              2
            ]
        ]
    }
}

The various entries in .vertices are related by their array index. So in this case, the first vertex (id: 71597 - with an array index of 0) has attribute values 129748 and 129898 (with array indices 1 and two respectively).

I can get the array index for the attribute I'm searching for with the following jq filter:

.vertices | range(0;length) as $i | select(.[$i].alias=="polarized" and .[$i].ns=="ca") | $i

That returns an $i value of 0, since the object with alias "polarized" is the first item in the array. You can try it out here on jq play:

https://jqplay.org/s/DsHYi7ixyn

Now I want to use that $i value in a different filter, so instead of outputting 0 it outputs something like the result of this:

.edgeGroups.hasAttributeValue[] | select(.[0] == 0)

I've tried using the pipe operator like this but it just gives me an error:

.vertices | range(0;length) as $i | select(.[$i].alias=="polarized" and .[$i].ns=="ca") | .edgeGroups.hasAttributeValue[] | select(.[0] == $i)

If I could understand how to use the $i in a chained filter, I think I could solve my main goal, which is to chain several filters together so that I can get all the items associated with the 71597 object - i.e.

        {
          "id": 129748,
          "ns": "av",
          "name": "Polarized"
        },
        {
          "id": 129898,
          "ns": "av",
          "name": "False"
        }

Thanks for any help in advance!


Solution

  • Your jq filter could be fixed with a couple of parentheses:

    (.vertices
     | range(0;length) as $i
     | select(.[$i].alias=="polarized" and .[$i].ns=="ca")
     | $i) as $i
    | .edgeGroups.hasAttributeValue[]
    | select(.[0] == $i)