5

I want to conditionally update an element value based on the value of another element within the same array.

For example, I want to find name=="weather" and change checked from "true" to "false"

[
  {
    "originalSourceId": null,
    "sourceConnection": {
      "id": null,
      "version": null,
      "properties": [
        {
          "id": null,
          "version": null
        }
      ],
      "name": "POSTGRESQL",
      "businessName": null
    },
    "checked": true,
    "newlyAdded": false,
    "discoveredEntities": [
      {
        "name": "weather",
        "checked": true,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      },
      {
        "name": "weather_2",
        "checked": true,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      }
    ],
    "defaultLevel": "MANAGED"
  }
]

the checked element will update to "false" for the same object with name = "weather"

[
  {
    "originalSourceId": null,
    "sourceConnection": {
      "id": null,
      "version": null,
      "properties": [
        {
          "id": null,
          "version": null
        }
      ],
      "name": "POSTGRESQL",
      "businessName": null
    },
    "checked": true,
    "newlyAdded": false,
    "discoveredEntities": [
      {
        "name": "weather",
        "checked": false,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      },
      {
        "name": "weather_2",
        "checked": true,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      }
    ],
    "defaultLevel": "MANAGED"
  }
]
1
  • I've tried jq . | jq '[.[].discoveredEntities[] | if (.name=="weather") then (.checked = "false") else . end]' ./test.json. But it is only return portion of it back with updated checked = false for weather. </pre>[ { "name": "weather", "checked": "false", "checkedBeforeEdit": false, "storeFieldsAsStrings": false }, { "name": "weather_2", "checked": true, "checkedBeforeEdit": false, "storeFieldsAsStrings": false } ]<code> Commented Sep 4, 2018 at 18:13

3 Answers 3

4

Figured it out.

jq '[.[].discoveredEntities[] |= if (.name=="weather") then (.checked = "false") else . end]'\
    ./test.json
Sign up to request clarification or add additional context in comments.

2 Comments

You don't need the outer square brackets [], in this context, you're putting the results in an array. But since the body is just assignments, the initial input will always be returned. You'll end up with your original input updated, but in an array.
It would be more consistent with the remainder of the document to use the boolean value false rather than the string "false".
3

For these sorts of updates, it's easier to visualize if you think of it this way, locate the items you want to update first, then update them.

 (.[].discoveredEntities[] | select(.name == "weather").checked) = false
#[ locate the items to update                         ]
#                                                      [ update them   ]

1 Comment

While the update works, it has an unintended side effect of returning filtered results. Is there any way to include unmodified items to the result set?
0

Using map here yields a very straightforward if somewhat pedestrian solution:

map( .discoveredEntities |=
        map(if .name == "weather" then .checked = false else . end))

Note that it is evidently more appropriate to use false here rather than "false".

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.