2

I'm trying to use jq to modify json data at various levels of an API request or response to enable support for API versioning.

Here's my (simplified) test JSON:

[
  {
    "note": null,
    "patient_id": 1,
    "phenotypes": [
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 1,
        "person_id": 1
      },
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 1,
        "person_id": 1
      }
    ]
  },
  {
    "note": null,
    "patient_id": 2
  },
  {
    "note": null,
    "patient_id": 3,
    "phenotypes": [
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 3,
        "person_id": 3
      },
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 3,
        "person_id": 3
      }
    ]
  }
]

I have an array of objects. Each object MAY have "phenotypes", which I need to modify the content of, as well as removing "note" from the top level object.

Currently my jq is as follows:

[ map(del(.note, .age)) | .[] | select(.phenotypes != null) | .phenotypes |= map(del(.person_id)) ]

This almost works, but because of select(.phenotypes != null), the second object in the array never makes it back after filtering.

I have also tried using if-then-else (end), however I couldn't make it not error, and I can't find any examples or documentation that suggests it can be used for further expression.

My expected output is the following:

[
  {
    "patient_id": 1,
    "phenotypes": [
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 1
      },
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 1
      }
    ]
  },
  {
    "patient_id": 2
  },
  {
    "patient_id": 3,
    "phenotypes": [
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 3
      },
      {
        "name": "Breast carcinoma",
        "observation": "present",
        "patient_id": 3
      }
    ]
  }
]

note has been removed from root. person_id has been removed from phenotypes.

1
  • I have included the expected output. Thanks. Commented Jul 20, 2018 at 11:27

1 Answer 1

3

This works for me:

map(del(.note, .age)) |
map( 
    if .phenotypes then 
        (.phenotypes |= map(del(.person_id)))
    else
        .
    end 
)

Working example

Sign up to request clarification or add additional context in comments.

3 Comments

I think when I tried to use if, I hadn't realised that else was required.
I was trying to solve it using .phenotypes? but couldn't get it to stick. This way probably isn't that elegant, but there's always multiple ways of solving this stuff.
I saw other answers which suggested something similar, but I couldn't make that work either. I also tried ` // []` to get around the null issue, but it didn't like that either.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.