Search code examples
jsonjqunique-id

How to generate continuing indices for multiple objects in nested arrays that are in an array


Given

[{
  "objects": [{
    "key": "value"
  },{
    "key": "value"
  }]
}, {
  "objects": [{
    "key": "value"
  }, {
    "key": "value"
  }]
}]

How do I generate

[{
  "objects": [{
    "id": 0,
    "key": "value"
  },{
    "id": 1,
    "key": "value"
  }]
}, {
  "objects": [{
    "id": 2,
    "key": "value"
  }, {
    "id": 3,
    "key": "value"
  }]
}]

Using jq?

I tried to use this one, but ids are all 0:

jq '[(-1) as $i | .[] | {objects: [.objects[] | {id: ($i + 1 as $i | $i), key}]}]'

Solution

  • The key to a simple solution here is to break the problem down into easy pieces. This can be accomplished by defining a helper function, addId/1. Once that is done, the rest is straightforward:

    # starting at start, add {id: ID} to each object in the input array 
    def addId(start):
      reduce .[] as $o
        ([];
         length as $l 
         | .[length] = ($o | (.id = start + $l)));
    
    reduce .[] as $o
      ( {start: -1, answer: []};
        (.start + 1) as $next
        | .answer += [$o | (.objects |= addId($next))]
        | .start += ($o.objects | length) )
    | .answer