Você pode me explicar como os dois seguintes diferem?
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]]
Obrigado.
Responder1
Resumo: As duas funções e a maneira como você as chama diferem no local onde a map()
operação acontece e no que é usado na adição. Isso importa porque no primeiro caso, map()
a chamada faz com que a adição na função use o primeiro elemento decada submatriz individualda matriz de entrada. No segundo caso, o map()
é realizado dentro da função, e a adição é feita usandotoda a primeira submatrizda matriz de entrada.
Na primeira função,
def addvalue(f): . + [f];
você adiciona a matriz [f]
ao que é considerado uma matriz no fluxo de entrada. Adicionar um array a outro array tem o efeito de acrescentar novos elementos ao array.
Você chama essa addvalue()
função duas vezes usando map()
; uma vez para cada uma das matrizes [1,2]
e [10,20]
. Na primeira chamada, [f]
será [1]
, então você adiciona 1
um novo elemento no primeiro array, produzindo [1,2,1]
. Da mesma forma, você recebe [10,20,10]
na segunda chamada quando [f]
is [10]
.
Adicionando depuração à função,
def addvalue(f): debug | . + [f]
obtemos o seguinte ao chamá-lo como na pergunta:
["DEBUG:",[1,2]]
["DEBUG:",[10,20]]
Isso mostra que a função é chamada duas vezes. O valor [f]
estaria [1]
na primeira chamada, resultando na operação [1,2] + [1]
, dando [1,2,1]
, e [10]
na segunda chamada, [10,20] + [10]
resultando em [10,20,10]
. A map()
operação na chamada combinaria essas matrizes em [[1,2,1],[10,20,10]]
.
Na função
def addvalue(f): f as $x | map(. + $x);
você chama map()
o que é considerado um array no fluxo de entrada. Para cada elemento na matriz de entrada você adiciona $x
a esse elemento. O valor de $x
é o primeiro elemento da matriz.
Você chama essa função uma vez, com o array [[1,2],[10,20]]
como array de entrada e com [1,2]
como argumento. Para cada um dos elementos do array de entrada, ou seja, para [1,2]
e [10,20]
, você adiciona [1,2]
(o valor de $x
, o primeiro elemento do array). Adicionar um array a outro array tem o efeito de anexar os elementos dos arrays uns aos outros, então você acaba com [1,2,1,2]
e [10,20,1,2]
como dois elementos do array resultante.
Habilitando a depuração na segunda função de maneira semelhante à primeira,
def addvalue(f): debug | f as $x | map(. + $x);
obtemos como saída
["DEBUG:",[[1,2],[10,20]]]
Isso mostra que a função é chamada uma única vez. A map()
operação criaria um array onde cada elemento do array de entrada seria [1,2]
adicionado a si mesmo, dando [[1,2,1,2],[10,20,1,2]]
como resultado.
Para fazer a primeira função agir como a segunda, você teria que chamá-la usando
.[0] as $x | map(addvalue($x[]))
Para fazer a segunda função agir como a primeira, você teria que chamá-la como
[ .[] as $x | [$x] | addvalue([$x[0]]) | add ]