5

this is my data structure:

[
    {
        "name": "name1",
        "organizations": [
            {
                "name": "name2",
                "spaces": [
                    {
                        "name": "name3",
                        "otherkey":"otherval"
                    },
                    {
                        "name": "name4",
                        "otherkey":"otherval"
                    }
                ]
            }
        ]
    },
    {
        "name": "name21",
        "organizations": [
            {
                "name": "name22",
                "spaces": [
                    {
                        "name": "name23",
                        "otherkey":"otherval"
                    },
                    {
                        "name": "name24",
                        "otherkey":"otherval"
                    }
                ]
            }
        ]
    }
]

i just want to keep name=name1, remove the nested array object with name=name4 and want to keep the rest of the object intact. I tried with map(select) but this will just give me the full object. Is it possible to work with del on specific subarrays and keep the rest as it is?

result should be the following. in addition i want to avoid enumeration all attributes to keep on outer objects:

[
    {
        "name": "name1",
        "organizations": [
            {
                "name": "name2",
                "spaces": [
                    {
                        "name": "name3",
                        "otherkey":"otherval"
                    }
                ]
            }
        ]
    }
]

any idea? thanks!

4 Answers 4

5

A very targeted solution would be:

path(.[0].organizations[0].spaces) as $target
| (getpath($target) | map(select(.name != "name4"))) as $new
| setpath($target; $new)

If permissible, though, you might consider:

walk(if type == "object" and .spaces|type == "array"
     then .spaces |= map(select(.name != "name4"))
     else . end)

or:

del(.. | .spaces? // empty | .[] | select(.name == "name4") )

(If your jq does not have walk/1 then its jq definition can easily be found by googling.)

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

Comments

1

You can use the below and it will remove the "name": "name4" array only.

jq 'del(.[] | .organizations? | .[] | .spaces?|.[] | select(.name? == "name4"))' yourJsonFile.json

Comments

0

Here is a solution using select, reduce, tostream and delpaths

map(  
    select(.name == "name1")
  | reduce (tostream|select(length==2)) as [$p,$v] (
      .
    ; if [$p[-1],$v] == ["name","name4"] then delpaths([$p[:-1]]) else . end
    )
)

Comments

0

I took a similar approach as @peak but inverted it, so instead of selecting what you want and setting that in the output we're selecting what we don't want and deleting it.

[path(.organizations[0].spaces[]| select(.name == "name4")] as $trash | delpaths($trash)

Comments

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.