Ricorda che un programma jq è una pipeline di espressioni.
L'assegnazione di variabile segue questa regola: un'assegnazione di variabile è un'espressione che ha questa forma:
... | expr as $varname | ...
Come per l'espressione di identità ., l'output dell'assegnazione di variabile è uguale al suo input.
Impostare il valore della variabile è un effetto collaterale.
Ecco un esempio che mostra come . dopo l'assegnazione sia uguale all'input iniziale:
$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]
Lo scope della variabile è «lessicale»: la variabile resterà nello scope per il resto della pipeline. Le variabili definite all'interno delle funzioni (arriveremo alle funzioni più avanti) sono «locali» alla funzione.
Il nome di una variabile deve iniziare con $.
Il resto del nome della variabile è un identificatore: inizia con una lettera o un underscore, seguito da lettere, numeri o underscore.
Dal manuale:
Più variabili possono essere dichiarate con una singola espressione
as, fornendo un pattern che corrisponde alla struttura dell'input (questa operazione è nota come «destrutturazione»).
Esempi:
[1, 2, 3] as [$a, $b, $c]
| [$a, $b, $c] # => [1, 2, 3]
{"foo": "bar", "len": [10, 20]} as {foo: $f, len: [$h, $w]}
| [$f, $h, $w] # => ["bar", 10, 20]
Far coincidere il nome della variabile con la chiave dell'oggetto offre una scorciatoia:
{"x": 4, "y": 7} as {$x, $y}
| [$x, $y] # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len] # => ["bar", [10, 20]]
La stessa scorciatoia funziona anche al contrario per la costruzione di oggetti
4 as $x | 7 as $y | {$x, $y} # => {"x":4, "y": 7}
Come mostra l'esempio qui sopra, le variabili sono comode per memorizzare costanti. È meglio dare un nome alle costanti invece di lasciare che dei «numeri magici» compaiano nel codice.
Spesso è più leggibile omettere le variabili.
Prendiamo il calcolo della media di un array di numeri
[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len
rispetto a
[2, 4, 8, 7] | add / length
Questo mette in luce uno degli aspetti più potenti di jq: l'input di un filtro viene fornito a ogni sottoespressione:
[2,4,8,7] viene passato ad add (che somma i numeri applicando l'operatore + a tutti gli elementi)[2,4,8,7] viene passato anche a length
jq che ti serviranno per l'esercizio di apprendimento//
L'espressione a // b produce b se a è false o null, altrimenti produce a.
Nel contesto dell'assegnazione di una variabile, è molto comoda per fornire un valore predefinito:
(.input.theAnswer // 42) as $answer | ...
+, -, * sono i soliti operatori numerici di addizione, sottrazione e moltiplicazione.In questo esercizio scriverai un po' di codice per aiutarti a preparare una lasagna eccezionale, seguendo il tuo libro di ricette preferito.
Hai quattro compiti, tutti legati al tempo impiegato per cucinare la lasagna.
Definisci una costante chiamata $expected_minutes_in_oven.
Secondo il libro di ricette, il tempo di cottura previsto in minuti è 40:
$ jq -n -f lasagna.jq
{
"expected_minutes_in_oven": 40,
...
Questo valore prende come input i minuti effettivi in cui la lasagna è rimasta nel forno e restituisce quanti minuti deve ancora rimanere la lasagna nel forno, in base al tempo di cottura previsto in minuti del compito precedente.
$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
"expected_minutes_in_oven": 40,
"remaining_minutes_in_oven": 22,
...
Il tempo di preparazione è quanto ci vuole per preparare la lasagna prima di metterla nel forno. Servono 2 minuti per preparare ogni strato.
$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
...
"preparation_time": 6,
...
Calcola quanti minuti in totale hai lavorato per cucinare la lasagna. È la somma del tempo di preparazione in minuti e del tempo in minuti che la lasagna ha trascorso nel forno fino a questo momento.
$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
...
"total_time": 14,
...
Iscriviti a Exercism per imparare e padroneggiare jq con 12 concetti75 esercizi e il mentoring di persone reali, tutto gratis.