Definieren von Funktionen und Verwenden von Maps in jq

Definieren von Funktionen und Verwenden von Maps in jq

Können Sie mir erklären, worin sich die folgenden beiden unterscheiden?

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]]

Danke.

Antwort1

Zusammenfassung: Die beiden Funktionen und die Art und Weise, wie Sie sie aufrufen, unterscheiden sich darin, wo die map()Operation stattfindet und was bei der Addition verwendet wird. Dies ist wichtig, da im ersten Fall map()der Aufruf bewirkt, dass die Addition in der Funktion das erste Element von verwendetjedes einzelne Subarraydes Eingabearrays. Im zweiten Fall map()wird die Funktion innerhalb der Funktion ausgeführt und die Addition erfolgt mitdas gesamte erste Subarraydes Eingabearrays.


In der ersten Funktion

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

Sie fügen das Array [f]zu dem hinzu, was als Array im Eingabestream angenommen wird. Das Hinzufügen eines Arrays zu einem anderen Array bewirkt, dass dem Array neue Elemente hinzugefügt werden.

Sie rufen diese addvalue()Funktion zweimal mit auf map(); einmal für jedes der Arrays [1,2]und [10,20]. Beim ersten Aufruf [f]wird sein [1], also fügen Sie 1als neues Element im ersten Array hinzu, was ergibt [1,2,1]. Ebenso erhalten Sie [10,20,10]beim zweiten Aufruf, wenn [f]ist [10].

Hinzufügen von Debugging zur Funktion,

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

Beim Aufruf wie in der Frage erhalten wir folgendes:

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

Dies zeigt, dass die Funktion zweimal aufgerufen wird. Der Wert [f]wäre [1]im ersten Aufruf, was zur Operation führt [1,2] + [1], was ergibt [1,2,1], und [10]im zweiten Aufruf mit, [10,20] + [10]was zu ergibt [10,20,10]. Die map()Operation im Aufruf würde diese Arrays zu kombinieren [[1,2,1],[10,20,10]].


In der Funktion

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

Sie rufen map()auf, was vermutlich ein Array im Eingabestrom ist. Für jedes Element im Eingabearray fügen Sie $xdiesem Element etwas hinzu. Der Wert $xist das erste Element des Arrays.

Sie rufen diese Funktion einmal auf, mit dem Array [[1,2],[10,20]]als Eingabearray und mit [1,2]als Argument. Für jedes der Elemente des Eingabearrays, also für [1,2]und [10,20], fügen Sie [1,2](den Wert von $x, dem ersten Element des Arrays) hinzu. Das Hinzufügen eines Arrays zu einem anderen Array bewirkt, dass die Elemente der Arrays aneinander angehängt werden, sodass Sie am Ende [1,2,1,2]und [10,20,1,2]als zwei Elemente des resultierenden Arrays erhalten.

Aktivieren Sie das Debuggen in der zweiten Funktion auf ähnliche Weise wie in der ersten.

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

erhalten wir als Ausgabe

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

Dies zeigt, dass die Funktion nur einmal aufgerufen wird. Die map()Operation würde ein Array erstellen, in dem jedes Element des Eingabearrays [1,2]zu sich selbst addiert wird, was [[1,2,1,2],[10,20,1,2]]das Ergebnis ergibt.


Damit die erste Funktion als zweite fungiert, müssen Sie sie mit folgendem Befehl aufrufen:

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

Damit die zweite Funktion wie die erste wirkt, müsste man sie wie folgt aufrufen:

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

verwandte Informationen