Definindo funções e usando map em jq

Definindo funções e usando map em jq

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 1um 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 $xa 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 ]

informação relacionada