Rutas
/
jq
jq
/
Ejercicios
/
Lasaña
Lasaña

Lasaña

Ejercicio de aprendizaje

Introducción

Variables

Recuerda que un programa de jq es un pipeline de expresiones. La asignación de variables sigue esta regla: una asignación de variable es una expresión con esta forma:

... | expr as $varname | ...

La salida del filtro es la entrada

Al igual que la expresión de identidad ., la salida de la asignación de variable es la misma que su entrada. Establecer el valor de la variable es un efecto secundario.

Ejemplo que muestra que . después de la asignación es igual que la entrada inicial:

$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]

Scope de las variables

El scope de la variable es «léxico»: la variable estará en scope durante el resto del pipeline. Las variables definidas en funciones (ya llegaremos a las funciones) son «locales» a la función.

Nombres de las variables

La variable debe empezar por $. El resto del nombre de la variable es un identificador: empieza por una letra o un guion bajo, seguido de letras, números o guiones bajos.

Asignación por desestructuración

Del manual:

Se pueden declarar varias variables con una única expresión as proporcionando un patrón que coincide con la estructura de la entrada (esto se conoce como «desestructuración»).

Ejemplos:

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

Hacer coincidir el nombre de la variable con la clave del objeto ofrece un atajo:

{"x": 4, "y": 7} as {$x, $y}
| [$x, $y]         # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len]     # => ["bar", [10, 20]]
Note

El mismo atajo funciona en el sentido inverso para la construcción de objetos

4 as $x | 7 as $y | {$x, $y}    # => {"x":4, "y": 7}

Constantes

Como se muestra en el ejemplo anterior, las variables resultan útiles para almacenar constantes. Es mejor dar un nombre a las constantes en lugar de que aparezcan «números mágicos» en el código.

A menudo las variables no son necesarias

A menudo es más legible omitir las variables.

Considera el cálculo de la media de un array de números

[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len

en comparación con

[2, 4, 8, 7] | add / length

Esto pone de relieve uno de los aspectos más potentes de jq: la entrada de un filtro se proporciona a todas las subexpresiones:

  • el array de entrada [2,4,8,7] se pasa a add (que suma los números aplicando el operador + a todos los elementos)
  • en paralelo, [2,4,8,7] también se pasa a length
  • cuando estas subexpresiones terminan, sus resultados se dividen, lo que devuelve el valor medio de los números del array de entrada.

Operadores de jq que necesitarás para el ejercicio de aprendizaje

Operador alternativo: //

La expresión a // b produce b si a es falso o null; en caso contrario, produce a. En el contexto de asignar una variable, resulta muy útil para proporcionar un valor predeterminado:

(.input.theAnswer // 42) as $answer | ...
Operadores aritméticos
  • +, - y * son los operadores habituales de suma, resta y multiplicación de números.

Instrucciones

En este ejercicio vas a escribir algo de código que te ayudará a preparar una lasaña espectacular con tu libro de cocina favorito.

Tienes cuatro tareas, todas relacionadas con el tiempo que se tarda en cocinar la lasaña.

1. Define el tiempo esperado en el horno en minutos

Define una constante llamada $expected_minutes_in_oven. Según el libro de cocina, el tiempo esperado en el horno en minutos es 40:

$ jq -n -f lasagna.jq
{
  "expected_minutes_in_oven": 40,
  ...

2. Calcula el tiempo restante en el horno en minutos

Este valor toma como entrada los minutos reales que la lasaña lleva en el horno y devuelve cuántos minutos le quedan todavía por permanecer en el horno, según el tiempo esperado en el horno en minutos de la tarea anterior.

$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
  "expected_minutes_in_oven": 40,
  "remaining_minutes_in_oven": 22,
  ...

3. Calcula el tiempo de preparación en minutos

El tiempo de preparación es lo que se tarda en dejar la lasaña lista antes de meterla en el horno. Se tardan 2 minutos en preparar cada capa.

$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
  ...
  "preparation_time": 6,
  ...

4. Calcula el tiempo total de trabajo en minutos

Calcula cuántos minutos en total has trabajado en cocinar la lasaña. Es la suma del tiempo de preparación en minutos y el tiempo en minutos que la lasaña lleva en el horno en ese momento.

$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
  ...
  "total_time": 14,
  ...
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
jq Exercism

¿Listo para empezar Lasaña?

Regístrate en Exercism para aprender y dominar jq con 12 conceptos75 ejercicios y mentoría humana real, todo gratis.