previously I posted a question here (Create a list from json file, with multiple values). However, I found some of my keys are outdated, and they contain a key called "end". I was not able to filter them out, making the data erratic.
Here's the updated JSON that I use for testing:
[
{
"primary": "JOHN DOE",
"attributes": [
{
"type": "double",
"name": "BUILDING_NUMBER",
"value": "123"
},
{
"type": "double",
"name": "FLOOR",
"value": 10
},
{
"type": "string",
"name": "EMAIL",
"value": "[email protected]"
},
{
"type": "string",
"name": "JOB_TITLE",
"value": "SALESMAN"
},
{
"type": "string",
"name": "JOB_TITLE",
"value": "TRAINEE",
"end": "11-09-2022"
}
],
"aliases": [
{
"alias": "[email protected]"
}
]
},
{
"primary": "LORRAINE DOE",
"attributes": [
{
"type": "double",
"name": "BUILDING_NUMBER",
"value": 456
},
{
"type": "double",
"name": "FLOOR",
"value": 10
},
{
"type": "string",
"name": "STATUS",
"value": "Unavaliable"
},
{
"type": "string",
"name": "EMAIL",
"value": "[email protected]"
},
{
"type": "string",
"name": "JOB_TITLE",
"value": "Procurement",
"end": "11-09-2021"
},
{
"type": "string",
"name": "JOB_TITLE",
"value": "SECRETARY"
},
{
"type": "string",
"name": "JOB_TITLE",
"value": "SALES",
"end": "11-09-2021"
}
],
"aliases": [
{
"alias": "[email protected]"
},
{
"alias": "[email protected]"
}
]
},
{
"primary": "JACK DOE",
"attributes": [
{
"type": "double",
"name": "BUILDING_NUMBER",
"value": "123"
},
{
"type": "double",
"name": "FLOOR",
"value": 10
},
{
"type": "string",
"name": "JOB_TITLE",
"value": "OWNER"
}
],
"aliases": [
{
"alias": "[email protected]"
},
{
"alias": "[email protected]"
}
]
},
{
"primary": "NOAH DOE",
"attributes": [
{
"type": "double",
"name": "BUILDING_NUMBER",
"value": "123"
},
{
"type": "double",
"name": "FLOOR",
"value": 10
},
{
"type": "string",
"name": "EMAIL",
"value": "[email protected]"
}
],
"aliases": [
{
"alias": "[email protected]"
}
]
}
]
Is there a way to filter out the attributes with key "end" and make the result as below?
"[email protected]": "SALESMAN",
"[email protected]": "SECRETARY"
This is the old solution:
.[].attributes | from_entries
| select(has("JOB_TITLE") and has("EMAIL"))
| "\"\(.EMAIL)\": \"\(.JOB_TITLE)\""
CodePudding user response:
Filter them out using a map
before running from_entries
:
.[].attributes
| map(select(.name != "JOB_TITLE" or (has("end") | not)))
| from_entries
| select(has("JOB_TITLE") and has("EMAIL"))
| "\"\(.EMAIL)\": \"\(.JOB_TITLE)\""
"[email protected]": "SALESMAN"
"[email protected]": "SECRETARY"
CodePudding user response:
Before converting the attributes to objects, select only those which do not have an end
property:
.[].attributes
| map(select(has("end")|not)) # <- this line is new
| from_entries
| select(has("JOB_TITLE") and has("EMAIL"))
| "\"\(.EMAIL)\": \"\(.JOB_TITLE)\""
Output:
"[email protected]": "SALESMAN"
"[email protected]": "SECRETARY"