0

I have a JSON object that looks like this:

{ "a": [{ "last": "other", "b": [{ "first": "John", "last": "Doe" }] }, { "last": "other", "b": [{ "first": "Jane", "last": "Doe" }] }, { "last": "other", "b": [{ "first": "John", "last": "Smith" }] }] } 

I would like to use jq to turn this into a single array of objects based on the value of "last". The desired output would be something like this:

[{ "last": "Doe" }, { "last": "Smith" }] 

where only unique values of "last" that is a child of "b" are included. In my case I don't care about any of the other fields.

1 Answer 1

1

Here's a solution to the original question that uses .. (i.e., that scans for objects with a "last" key, wherever they may be):

[.. | select(.last?).last] | unique | map({last: .}) 

This can easily be modified to solve the revised question:

[.. | select( (.b?|type) == "array") | .b[] | select(.last?).last ] | unique | map({last: .}) 

Caveat

unique performs a sort. If you want the order of .last values to be respected, then the following helper function can be used, provided all the .last values are strings:

def uniques(stream): foreach stream as $s ({}; if .[$s] then .emit = false else .emit = true | (.item = $s) | (.[$s]=true) end; if .emit then .item else empty end ); 
| [ uniques(.. | select(.b?).b[] | select(.last?).last) | {last: .}] 
Sign up to request clarification or add additional context in comments.

2 Comments

Your answer is 100% correct for my question. However, I simplified my example a bit too much when I asked the question. The actual data looks more like this: { "a": [{ "last": "other", "b": [{ "first": "John", "last": "Doe" }] }, { "last": "other", "b": [{ "first": "Jane", "last": "Doe" }] }, { "last": "other", "b": [{ "first": "John", "last": "Smith" }] }] } I don't want the "last" that is a peer to "b".
I updated the sample in my original post to more accurately reflect the data. I tried to rework your answer to solve it, but still not understanding this syntax I guess. Thanks for helping.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.