Можете ли вы объяснить мне, чем отличаются следующие два пункта?
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 ]