Home > other >  transform only subarray of objects in JQ
transform only subarray of objects in JQ

Time:12-13

I am trying to transform this JSON object:

{
  "id_1": {},
  "id_2": {
    "sys": "S",
    "details": [
      {
        "detail": "S1",
        "index": 0
      },
      {
        "detail": " ",
        "index": 1
      },
      {
        "detail": " ",
        "index": 2
      },
      {
        "detail": " ",
        "index": 3
      },
      {
        "detail": " ",
        "index": 4
      }
    ],
    "color": "Grey"
  },
  "id_3": {
    "sys": "A",
    "details": [
      {
        "detail": "240",
        "index": 0
      },
      {
        "detail": "63",
        "index": 1
      },
      {
        "detail": "70",
        "index": 2
      },
      {
        "detail": " ",
        "index": 3
      },
      {
        "detail": " ",
        "index": 4
      }
    ],
    "color": "White"
  },
  "id_4": {},
  "id_5": {
    "sys": "G",
    "details": [
      {
        "detail": "266",
        "index": 0
      },
      {
        "detail": "G",
        "index": 1
      },
      { 
        "detail": "1",
        "index": 2
      },
      {
        "detail": " ",
        "index": 3
      },
      {
        "detail": " ",
        "index": 4
      } 
    ],
    "color": "Red"
  }     
}

into that one:

{
  "id_1": {},
  "id_2": {
    "sys": "S",
    "details": ["S1"],
    "color": "Grey",
  },
  "id_3": {
    "sys": "A",
    "details": ["240","63","70"],
    "color": "White",
  },
  "id_4": {},
  "id_5": {
    "sys": "G",
    "details": ["266", "G", "1"],
    "color": "Red",
  }
}

There are also empty objects in the outer object that should be remained. Only the key details should be transformed, others should be kept.

Could not achive to create any valid query with map nor with select. The only valid jq I have created so far: .[]? | [.details[]? | select(.detail != " ")] | .[] .detail, but only results the details strings...

CodePudding user response:

Here is one way:

map_values(
  select(has("details")) .details |=
    map(.detail | select(. != " "))
)

Online demo

CodePudding user response:

You can also use values to empty objects not having a .details field (or having one with null as its value).

.[].details |= (values | map(.detail | select(. != " ")))
{
  "id_1": {},
  "id_2": {
    "sys": "S",
    "details": ["S1"],
    "color": "Grey"
  },
  "id_3": {
    "sys": "A",
    "details": ["240", "63", "70"],
    "color": "White"
  },
  "id_4": {},
  "id_5": {
    "sys": "G",
    "details": ["266", "G", "1"],
    "color": "Red"
  }
}

Demo

CodePudding user response:

Try this :

jq 'map_values(.details? |= map(select(.detail != " "))' file.json
  • Related