Need help to link several objects to one another (main object) with some specificities

Viewed 51

Need help to link several objects to one another (main object) with some specificities.

Hello, I need help to make this rendering from a JSON file. I tried several filters, I never managed to make it work the way I wanted. (This is a simplified example of my JSON file)

Input JSON:

[  
  {
    "id": "AAKG",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "PMBL",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "ZDFG",
    "data": "some data...",
    "main_id": "PMBL"
  },
  {
    "id": "XHGF",
    "data": "some data...",
    "main_id": "PMBL"
  },
  {
    "id": "LOKJ",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "JQWC",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "QQSZ",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "JQWC",
    "data": "some data...",
    "main_id": "QQSZ"
  },
  {
    "id": "LLRE",
    "data": "some data...",
    "main_id": "none"
  }
]

Output (what i want):

[  
  {
    "id": "AAKG",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "PMBL",
    "data": "some data...",
    "main_id": "none"
    "details": [
            {
                "id": "ZDFG",
                "data": "some data...",
                "main_id": "PMBL"
            },
            {
                "id": "XHGF",
                "data": "some data...",
                "main_id": "PMBL"
            }
        ]
  },
  {
    "id": "LOKJ",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "JQWC",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "QQSZ",
    "data": "some data...",
    "main_id": "none"
    "details": [
            {
                "id": "JQWC",
                "data": "some data...",
                "main_id": "QQSZ"
            }
        ]
  },
  {

  },
  {
    "id": "LLRE",
    "data": "some data...",
    "main_id": "none"
  }
]

Explanations:

In my input I have only one array that covers all the objects in my file, I would like to link all the objects in an Array that have in the "main_id" key value a specific value other than "none" (with key "details"), to the object (which I call the parent object) containing that same value in the "id" key of the parent object.

As you can see in my output example, which I think is more explicit than my explanations. Of course my real input file contains many more objects but the structure remains the same as in my example. [object,object,object,....]

1 Answers

A simple reduce with an if expression builig up an indexed object may suffice. The final map converts the object back to an array.

reduce .[] as $i ({};
  if $i.main_id == "none" then .[$i.id] += $i
  else .[$i.main_id].details += [$i] end
) | map(.)
[
  {
    "id": "AAKG",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "PMBL",
    "data": "some data...",
    "main_id": "none",
    "details": [
      {
        "id": "ZDFG",
        "data": "some data...",
        "main_id": "PMBL"
      },
      {
        "id": "XHGF",
        "data": "some data...",
        "main_id": "PMBL"
      }
    ]
  },
  {
    "id": "LOKJ",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "JQWC",
    "data": "some data...",
    "main_id": "none"
  },
  {
    "id": "QQSZ",
    "data": "some data...",
    "main_id": "none",
    "details": [
      {
        "id": "JQWC",
        "data": "some data...",
        "main_id": "QQSZ"
      }
    ]
  },
  {
    "id": "LLRE",
    "data": "some data...",
    "main_id": "none"
  }
]

Demo

Related