Как расширить область действия переменных jq 'as' для передачи внутри функций? - PullRequest
1 голос
/ 14 января 2020

С помощью jq я пытаюсь использовать записи в одном массиве для индексации в отдельный массив. Простой ввод JSON будет выглядеть так:

{
    "myArray": [ "AA", "BB", "CC", "DD", "EE" ],
    "myFlags": [ 4, 3, 2, 1, 0 ]
}

Изящный оператор 'jq' затем может вывести массив myArray в область видимости, и индексирование работает нормально:

.myArray as $Array | .myFlags | .[] | $Array[.]   ====> yields "EE","DD","CC","BB","AA"

Пока что JQ-руководство. Однако , если я попытаюсь переместить доступ к массиву $ Array вниз в функцию, область видимости переменной исчезнет:

def myFun: $Array[.]; .myArray as $Array | .myFlags | .[] | myFun

jq: error: $Array is not defined at <top-level>, line 1:
def myFun: $Array[.]; .myArray as $Array | .myFlags | .[] | myFun   

Чтобы обойти это, я сейчас передаю временный JSON объект, содержащий как индекс, так и массив:

def myFun: .a[.b]; .myArray as $Array | .myFlags | .[] | { a: $Array, b: . } | myFun

Хотя это работает, я должен сказать, что мне это не очень удобно.

Действительно, это не так мне кажется, что это правильное поведение языка jq. Мне кажется, что область «as» должна сохраняться в вызываемых def-функциях. : - (

Есть ли лучший способ расширения as-scope до def-функций? Я упускаю некоторые тонкости jq?

1 Ответ

1 голос
/ 14 января 2020

На самом деле можно сделать переменную «as» видимой внутри функции, не передавая ее в качестве параметра (см. «Лексическая область видимости» ниже), но это обычно не нужно, и на самом деле использование переменных «as» часто также не нужно.

Избежание переменной "as"

Вы можете упростить исходный запрос до:

.myArray[.myFlags[]]

Используя аргументы функции

Вы можете написать JQ-функции с одним или несколькими аргументами. Это подходящий способ параметризации фильтров.

Синтаксис довольно условен, за исключением того, что для функций с более чем одним аргументом точка с запятой (";") используется в качестве разделителя аргументов, как в определениях функций, так и в invocations.

Обратите также внимание, что аргументы функции jq сами могут быть фильтрами, например, вы можете написать:

def myFun(array; $ix): array | .[$ix];

myFun(.myArray; .myFlags[])

Лексическая область видимости

Вот пример, показывающий, как "как" переменную можно сделать видимой внутри функции:

[1,2] as $array | def myFun: $array[1]; myFun
...