Aidenhjj
Aidenhjj

Reputation: 1289

Delete different nested object if parent meets condition

I want to delete different sub-objects from a json file (whilst maintaining the original structure) depending on whether the parent object's key meets a given condition.

Say I have:

{
  "A": {
    "1": {
      "bar": 1,
      "foo": 0
    }
  },
  "B": {
    "2": {
      "not_here": 0,
      "foo": 0
    },
    "3": {
      "bar": 0,
      "foo": 1
    }
  },
  "C": {
    "4": {
      "bar": 0,
      "foo": 1
    }
  }
}

And for all nested objects with keys in ["1", "2"], I want to delete the bar object, and otherwise I want to delete the foo object, so the output expected being:

{
  "A": {
    "1": {
      "foo": 0
    }
  },
  "B": {
    "2": {
      "not_here": 0,
      "foo": 0
    },
    "3": {
      "bar": 0
    }
  },
  "C": {
    "4": {
      "bar": 0
    }
  }
}

I would've thought this would work:

.[][] |= (if .key == ("1", "2") then del(.bar) else del(.foo) end)

But there's something wrong with my conditional I think as it just deletes foo everywhere.

Upvotes: 0

Views: 294

Answers (1)

peak
peak

Reputation: 116880

Using your approach, you could write:

.[] |= with_entries(
   if (.key == "1" or .key == "2") 
   then .value |= del(.bar) 
   else .value |= del(.foo)
   end)

with_entries makes it easy to access each "key" and corresponding "value".

Your attempt failed because .[][] reaches down too deeply into the data, as you can see by running jq '.[][]'. If you do, you'll see why your attempt ends up deleting the foo keys unconditionally, the point being that .key is only defined for you in the context of with_entries (though to_entries can be used to achieve the same effect).

Upvotes: 1

Related Questions