Добавьте значения в массив JSON, если имя внешнего массива == 'something' - PullRequest
2 голосов
/ 13 июля 2020

Я передаю объект JSON в jq и хочу добавить дополнительные объекты во внутренний массив ('аксессуары'), если его родительский массив ('платформы') соответствует определенному имени.

Здесь мой источник JSON:

    {
        "bridge": {
            "name": "Homebridge",
            "port": 51395
        },
        "accessories": [],
        
        "platforms": [
            {
                "name": "Config",
                "port": 8581,
                "platform": "config"
            },
            {
                "platform": "homebridge-cbus.CBus",
                "name": "CBus",
                "client_ip_address": "127.0.0.1",
                "accessories": [
                    {
                      "values": "existing"
                    }
                ]
            }
        ]
    } 

Это прекрасно работает:

    jq '.platforms[1].accessories +=  [{ "values" : "NEW" }]'

... но, конечно, ожидать, что платформы [1] всегда будут иметь тот массив, который я хочу чтобы добавить, поэтому я попытался сформировать правильный синтаксис для поиска или if / then / else, чтобы действовать только на .name соответствующего.

Я думал, что это мое решение:

    jq '.platforms[] | if ( .name=="CBus" ) then .accessories += [{ "values" : "NEW" }] else . end'

... пока я не понял, что это всего лишь прохождение «платформ» через объект «мост» и пустой внешний массив «аксессуары», который мне нужно сохранить. проблема похожа на JQ | Обновление элемента массива, выбранного с помощью `select` , но я пробовал МНОГО комбинаций, но просто не могу прорваться.

Изменить: вот правильный JQPlay, который я был работает с:

https://jqplay.org/s/dGDswqAEte

Спасибо за любую помощь.

1 Ответ

2 голосов
/ 13 июля 2020

Это хорошая попытка. Ключевым моментом здесь является использование функции select() для идентификации объекта, который вы собираетесь обновить, и перезаписи всего массива с помощью оператора |=, то есть

.platforms |= ( map(select(.name == "CBus").accessories += [{ "values" : "NEW" }]  ) )

Для фрагмента в вашей ссылке jq-play (теперь удалено), вам нужно сделать

.gcp_price_list."CP-COMPUTEENGINE-OS" 
    |= with_entries(select(.value.cores == "shared").value.cores = "0.5")

Или, если вы хотите быть еще более конкретным c, и сохранить запись в gcp_price_list настраиваемой, выполните

.gcp_price_list |= 
with_entries ( 
  select(.key == "CP-COMPUTEENGINE-OS").value  |=  
with_entries(
  select(.value.cores == "shared").value.cores = "0.5") )
...