Home > Mobile >  JQ map with parent and child value
JQ map with parent and child value

Time:08-22

I have a bunch (hundreds) of JSON files with a parent child structure, e.g.

{
  "tables": [
    {
      "name": "TableA",
      "fields": [
        {
          "name": "FieldA"
        },
        {
          "name": "FieldB"
        }
      ]
    },
    {
      "name": "TableB",
      "fields": [
        {
          "name": "FieldA"
        },
        {
          "name": "FieldB"
        }
      ]
    }
  ]
}

and I want to add an extra field to the child object containing a value from the parent, e.g.

{
  "tables": [
    {
      "name": "TableA",
      "fields": [
        {
          "name": "FieldA",
          "fqn": "TableA_FieldA"
        },
        {
          "name": "FieldB",
          "fqn": "TableA_FieldB"
        }
      ]
    },
    {
      "name": "TableB",
      "fields": [
        {
          "name": "FieldA",
          "fqn": "TableB_FieldA"
        },
        {
          "name": "FieldB",
          "fqn": "TableB_FieldB"
        }
      ]
    }
  ]
}

Since there are so many files I'd like to process them automatically, and it feels like this should be doable with JQ, but I can't seem to work out how. Is anyone able to help?

CodePudding user response:

Use the update operator |= to retain the contexts while storing the .name values in variables using as:

.tables[] |= (
  .name as $tname | .fields[] |= (
    .name as $fname | .fqn = "\($tname)_\($fname)"
  )
)
{
  "tables": [
    {
      "name": "TableA",
      "fields": [
        {
          "name": "FieldA",
          "fqn": "TableA_FieldA"
        },
        {
          "name": "FieldB",
          "fqn": "TableA_FieldB"
        }
      ]
    },
    {
      "name": "TableB",
      "fields": [
        {
          "name": "FieldA",
          "fqn": "TableB_FieldA"
        },
        {
          "name": "FieldB",
          "fqn": "TableB_FieldB"
        }
      ]
    }
  ]
}

Demo

CodePudding user response:

The following is equivalent to @pmf's solution but is perhaps a little less magical (it uses map as suggested in the question), and only introduces one variable:

.tables |= map( .name as $name | .fields |= map( .fqn = "\($name)_\(.name)" ))
  • Related