Rappelle-toi qu'un programme jq est un pipeline d'expressions.
L'affectation de variable suit cette règle : une affectation de variable est une expression qui ressemble à :
... | expr as $varname | ...
Comme l'expression d'identité ., la sortie de l'affectation de variable est identique à son entrée.
Définir la valeur de la variable est un effet de bord.
Exemple qui montre que . après l'affectation est identique à l'entrée initiale :
$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]
La portée de la variable est « lexicale » : la variable reste dans la portée pour le reste du pipeline. Les variables définies dans des fonctions (on verra les fonctions plus tard) sont « locales » à la fonction.
Le nom de la variable doit commencer par $.
Le reste du nom de la variable est un identifiant : il commence par une lettre ou un tiret bas, suivi de lettres, de chiffres ou de tirets bas.
D'après le manuel :
On peut déclarer plusieurs variables avec une seule expression
asen fournissant un motif qui correspond à la structure de l'entrée (c'est ce qu'on appelle la « déstructuration »).
Exemples :
[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]
Faire correspondre le nom de la variable à la clé de l'objet offre un raccourci :
{"x": 4, "y": 7} as {$x, $y}
| [$x, $y] # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len] # => ["bar", [10, 20]]
Le même raccourci fonctionne dans le sens inverse pour la construction d'objets
4 as $x | 7 as $y | {$x, $y} # => {"x":4, "y": 7}
Comme le montre l'exemple ci-dessus, les variables sont pratiques pour stocker des constantes. Il vaut mieux donner un nom aux constantes plutôt que de laisser des « nombres magiques » apparaître dans le code.
Il est souvent plus lisible d'omettre les variables.
Prenons le calcul de la moyenne d'un tableau de nombres
[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len
comparé à
[2, 4, 8, 7] | add / length
Cela met en évidence l'un des aspects les plus puissants de jq : l'entrée d'un filtre est fournie à chaque sous-expression :
[2,4,8,7] est transmis à add (qui additionne les nombres en appliquant l'opérateur + à tous les éléments)[2,4,8,7] est aussi transmis à length
jq dont tu auras besoin pour l'exercice d'apprentissage//
L'expression a // b renvoie b si a vaut false ou null, sinon elle renvoie a.
Dans le contexte de l'affectation d'une variable, c'est très pratique pour fournir une valeur par défaut :
(.input.theAnswer // 42) as $answer | ...
+, - et * sont les opérateurs habituels d'addition, de soustraction et de multiplication numériques.Dans cet exercice, tu vas écrire du code pour t'aider à préparer une excellente lasagne tirée de ton livre de recettes préféré.
Tu as quatre tâches, toutes liées au temps passé à cuisiner la lasagne.
Définis une constante nommée $expected_minutes_in_oven.
D'après le livre de recettes, le temps de cuisson prévu au four est de 40 minutes :
$ jq -n -f lasagna.jq
{
"expected_minutes_in_oven": 40,
...
Cette valeur prend en entrée les minutes que la lasagne a déjà passées au four et renvoie le nombre de minutes qu'il lui reste à y passer, d'après le temps de cuisson prévu au four de la tâche précédente.
$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
"expected_minutes_in_oven": 40,
"remaining_minutes_in_oven": 22,
...
Le temps de préparation correspond au temps nécessaire pour préparer la lasagne avant de la mettre au four. Il faut 2 minutes pour préparer chaque couche.
$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
...
"preparation_time": 6,
...
Calcule le nombre total de minutes que tu as passées à cuisiner la lasagne. C'est la somme du temps de préparation en minutes et du temps que la lasagne a passé au four jusqu'à présent.
$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
...
"total_time": 14,
...
Inscris-toi sur Exercism pour apprendre et maîtriser jq avec 12 concepts75 exercices, et un vrai mentorat humain, le tout gratuitement.