chx
chx

Reputation: 11760

Getting an object key based on subarray value

I have a JSON defining some services:

{
  "services": {
    "main_content_renderer.off_canvas": {
      "class": "Drupal\\settings_tray\\Render\\MainContent\\OffCanvasRenderer",
      "arguments": [
        "@title_resolver",
        "@renderer"
      ],
      "tags": [
        {
          "name": "render.main_content_renderer",
          "format": "drupal_dialog.off_canvas"
        }
      ]
    },
    "access_check.settings_tray.block.settings_tray_form": {
      "class": "Drupal\\settings_tray\\Access\\BlockPluginHasSettingsTrayFormAccessCheck",
      "tags": [
        {
          "name": "access_check",
          "applies_to": "_access_block_plugin_has_settings_tray_form"
        }
      ]
    }
  }
}

I would like to write a jq program which returns access_check.settings_tray.block.settings_tray_form for the input access_check.

I tried various things but I either get jq: error (at <stdin>:20): Cannot index array with string "name" or just a syntax error.

Examples:

jq '.services| to_entries|map(select(.value.tags.[].name == "access_check")))'

This leads to a syntax error: jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:

Or jq '.services| to_entries|map(select(.value.tags|.name == "paramconverter"))' results in

jq: error (at <stdin>:20): Cannot index array with string "name"

Edit: while the example doesn't show there can be multiple tags.

Upvotes: 0

Views: 236

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134881

So if I understand your inputs and outputs, you want a service name, if it contains a given tag name.

I would write it like so.

$ jq --arg name "access_check" '
.services | to_entries[] | select(any(.value.tags[].name; . == $name)).key
' input.json

You were close with your attempts, but there were some syntax issues:

  1. .value.tags.[].name
    By having the dot before the [], the syntax is now invalid. It should have been .value.tags[].name.
  2. .value.tags|.name
    tags is an array, it may not have a property called name.

Upvotes: 0

jq170727
jq170727

Reputation: 14665

Here is a solution. If the following filter is in filter.jq

  .services
| keys[] as $k
| .[$k]
| select(.tags[]?.name == $name)
| $k

and the sample data is in data.json then the command

$ jq -Mr --arg name 'access_check' -f filter.jq data.json

produces

access_check.settings_tray.block.settings_tray_form

Upvotes: 1

Related Questions