Определение функций и использование map в jq

Определение функций и использование map в jq

Можете ли вы объяснить мне, чем отличаются следующие два пункта?

jq ´def addvalue(f): . + [f]; map(addvalue(.[0]))´

[[1,2],[10,20]]
=> [[1,2,1], [10,20,10]]

jq ´def addvalue(f): f as $x | map(. + $x); addvalue(.[0])´
[[1,2],[10,20]]
=> [[1,2,1,2], [10,20,1,2]]

Спасибо.

решение1

Резюме: Две функции и способ их вызова отличаются тем, где map()происходит операция и что используется при сложении. Это важно, так как в первом случае map()вызов заставляет сложение в функции использовать первый элементкаждый отдельный подмассиввходного массива. Во втором случае map()выполняется внутри функции, а сложение происходит с помощьювесь первый подмассиввходного массива.


В первой функции

def addvalue(f): . + [f];

вы добавляете массив [f]к тому, что предполагается массивом во входном потоке. Добавление массива к другому массиву имеет эффект добавления новых элементов к массиву.

Вы вызываете эту addvalue()функцию дважды, используя map(); по одному разу для каждого из массивов [1,2]и [10,20]. В первом вызове [f]будет [1], поэтому вы добавляете 1как новый элемент в первый массив, получая [1,2,1]. Аналогично, вы получаете [10,20,10]из второго вызова, когда [f]есть [10].

Добавление отладки в функцию,

def addvalue(f): debug | . + [f]

при вызове, как в вопросе, получаем следующее:

["DEBUG:",[1,2]]
["DEBUG:",[10,20]]

Это показывает, что функция вызывается дважды. Значение [f]будет [1]в первом вызове, что приведет к операции [1,2] + [1], дающей [1,2,1], и [10]во втором вызове, что [10,20] + [10]приведет к [10,20,10]. map()Операция в вызове объединит эти массивы в [[1,2,1],[10,20,10]].


В функции

def addvalue(f): f as $x | map(. + $x);

вы вызываете map()то, что предполагается массивом во входном потоке. Для каждого элемента во входном массиве вы добавляете $xк этому элементу. Значение $x— это первый элемент массива.

Эту функцию вы вызываете один раз, с массивом [[1,2],[10,20]]в качестве входного массива и с [1,2]аргументом. Для каждого из элементов входного массива, то есть для [1,2]и [10,20], вы добавляете [1,2](значение $x, первый элемент массива). Добавление массива к другому массиву имеет эффект присоединения элементов массивов друг к другу, поэтому в итоге вы получаете [1,2,1,2]и [10,20,1,2]как два элемента результирующего массива.

Включение отладки во второй функции аналогично первой,

def addvalue(f): debug | f as $x | map(. + $x);

мы получаем на выходе

["DEBUG:",[[1,2],[10,20]]]

Это показывает, что функция вызывается один раз. Операция map()создаст массив, где каждый элемент входного массива [1,2]прибавил бы к себе, дав [[1,2,1,2],[10,20,1,2]]в качестве результата.


Чтобы заставить первую функцию действовать как вторая, вам придется вызвать ее с помощью

.[0] as $x | map(addvalue($x[]))

Чтобы вторая функция действовала как первая, вам придется вызвать ее как

[ .[] as $x | [$x] | addvalue([$x[0]]) | add ]

Связанный контент