SVC RVBRAND
SVC RVBRAND

Reputation: 3

Yield objects recursively in JQ

I have this list of json objects

{
  "id": 1,
  "ref": "id:2",
  "msg": "1"
}
{
  "id": 2,
  "ref": "none",
  "msg": "2"
}
{
  "id": 3,
  "ref": "none",
  "msg": "3"
}

I want to be able (let's say search(id) is a function). if I call search(1) it needs to return the list of objects from (id=1) and all the ref objects that follow until one of the object has "ref": "none" or the id it references does not exist in the list of objects.

"ref": "id:2",, references the object with (id=2). I want to get all those objects until the ref field of one object is none or makes reference to a non-existing id in the list like "ref:101" (id=101 is not in the list)

Desired output for search(1)

{
  "id": 1,
  "ref": "id:2",
  "msg": "1"
}
{
  "id": 2,
  "ref": "none",
  "msg": "2"
}

Upvotes: 0

Views: 132

Answers (1)

oguz ismail
oguz ismail

Reputation: 50775

You need to aggregate your inputs into an object where you can easily navigate first. Then the rest is going to be plain recursion.

Like, with -n/--null-input specified, something like this should work just fine:

def prepare:
  reduce inputs as $in ({};
    . + ($in | {"id:\(.id)": .})
  );
def search($id):
  def follow($ref):
    if has($ref) then .[$ref], follow(.[$ref].ref) else empty end;
  follow("id:\($id)");
prepare | search(1)

Online demo

Upvotes: 1

Related Questions