Jordi
Jordi

Reputation: 23257

jq: map object if field exists

This is my jq code:

def pick_nationality:
  {nation: {country: .NACIONALITAT, code: "some code"} };

def pick_surname:
  {name: {surname: .SURNAME, code: "some code"} };

map([pick_nationality, pick_surname])

Problem here appears when some of .NACIONALITAT or .SURNAME is not present on input objects:

{
  "SURNAME": "surname1"
}
{
  "NACIONALITAT": "nacionalitat1"
}

Result:

[
  [
    {
      "nation": {
        "country": null,
        "code": "some code"
      }
    },
    {
      "name": {
        "surname": "surname1",
        "code": "some code"
      }
    }
  ],
  [
    {
      "nation": {
        "country": "nacionalitat1",
        "code": "some code"
      }
    },
    {
      "name": {
        "surname": null,
        "code": "some code"
      }
    }
  ]
]

Problem is I need to avoid pick_natinality when .NATIONALITAT field is not present...

Desired result would be:

[
  [
    {
      "name": {
        "surname": "surname1",
        "code": "some code"
      }
    }
  ],
  [
    {
      "nation": {
        "country": "nacionalitat1",
        "code": "some code"
      }
    }
  ]
]

Any ideas?

Upvotes: 0

Views: 358

Answers (3)

ikegami
ikegami

Reputation: 386361

Just have the functions return nothing when the relevant field is missing.

def pick_nationality:
  select(.NACIONALITAT) |
  {nation: {country: .NACIONALITAT, code: "some code"} };

def pick_surname: 
  select(.SURNAME) |
  {name: {surname: .SURNAME, code: "some code"} };

map([pick_nationality, pick_surname])

Demo on jqplay

Upvotes: 2

Philippe
Philippe

Reputation: 26697

You can add a test before capture the value :

def pick_nationality:
  if has("NACIONALITAT")
  then {nation: {country: .NACIONALITAT, code: "some code"} }
  else empty end;

def pick_surname: 
  if has("SURNAME")
  then {name: {surname: .SURNAME, code: "some code"} }
  else empty end;

map([pick_nationality, pick_surname])

Upvotes: 1

Barbaros Özhan
Barbaros Özhan

Reputation: 65363

You can use del for the respective null values such as

jq -r 'del(.[][] | select(.nation.country == null and .name.surname== null))'

Demo

Upvotes: 1

Related Questions