Треки
/
jq
jq
/
Вправи
/
Лазанья
Лазанья

Лазанья

Навчальна вправа

Вступ

Змінні

Нагадаємо, що програма jq - це конвеєр виразів. Присвоєння змінної підкоряється такому правилу: присвоєння змінної - це вираз, який має такий вигляд:

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

Фільтр виводить вхідні дані

Як і вираз тотожності ., присвоєння змінної повертає на виході ті самі дані, що отримує на вході. Встановлення значення змінної - це побічний ефект.

Приклад, що показує: . після присвоєння - це ті самі дані, що й початковий вхід:

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

Область видимості змінної

Область видимості змінної є «лексичною»: змінна залишається видимою до кінця конвеєра. Змінні, визначені у функціях (до функцій ми дійдемо пізніше), є «локальними» для цієї функції.

Імена змінних

Назва змінної має починатися з $. Решта назви змінної - це ідентифікатор: він починається з літери або підкреслення, за якими йдуть літери, цифри або підкреслення.

Деструктуризаційне присвоєння

З документації:

За допомогою одного виразу as можна оголосити кілька змінних, надавши шаблон, який відповідає структурі вхідних даних (це називають «деструктуризацією»).

Приклади:

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

Збіг назви змінної з ключем обʼєкта дає змогу скористатися скороченням:

{"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

Те саме скорочення працює у зворотному напрямку й для конструювання обʼєктів

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

Константи

Як видно з наведеного вище прикладу, змінні зручні для зберігання констант. Краще дати константам імʼя, ніж допускати появу «магічних чисел» у коді.

Часто змінні не потрібні

Часто код стає зрозумілішим, якщо обійтися без змінних.

Розглянемо обчислення середнього значення масиву чисел

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

порівняно з

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

Це демонструє одну з найпотужніших рис jq: вхідні дані фільтра передаються кожному підвиразу:

  • вхідний масив [2,4,8,7] передається у add (який додає числа, застосовуючи оператор + до всіх елементів)
  • паралельно [2,4,8,7] також передається в length
  • коли ці підвирази завершуються, їхні результати діляться, повертаючи середнє значення чисел вхідного масиву.

Оператори jq, які знадобляться для цієї вправи

Альтернативний оператор: //

Вираз a // b видає b, якщо a має значення false або null, а інакше видає a. У контексті присвоєння змінної це дуже зручно, коли потрібно задати типове значення:

(.input.theAnswer // 42) as $answer | ...
Арифметичні оператори
  • +, -, * - це звичайні оператори додавання, віднімання та множення чисел.

Вказівки

У цій вправі ми напишемо трохи коду, який допоможе приготувати чудову лазанью з улюбленої книги рецептів.

На нас чекають чотири завдання, і всі вони повʼязані з часом, витраченим на приготування лазаньї.

1. Визначте очікуваний час запікання в духовці у хвилинах

Визначте константу з назвою $expected_minutes_in_oven. Згідно з книгою рецептів, очікуваний час запікання в духовці становить 40 хвилин:

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

2. Обчисліть залишковий час запікання в духовці у хвилинах

Це значення приймає як вхідні дані фактичну кількість хвилин, які лазанья вже провела в духовці, і повертає, скільки хвилин їй ще залишилося там провести, виходячи з очікуваного часу в духовці з попереднього завдання.

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

3. Обчисліть час підготовки у хвилинах

Час підготовки показує, скільки часу потрібно, щоб підготувати лазанью, перш ніж поставити її в духовку. На підготовку кожного шару потрібно 2 хвилини.

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

4. Обчисліть загальний час роботи у хвилинах

Обчисліть, скільки хвилин загалом ми витратили на приготування лазаньї. Це сума часу підготовки в хвилинах і часу, який лазанья на цей момент уже провела в духовці.

$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
  ...
  "total_time": 14,
  ...
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
jq Exercism

Час розпочати Лазанья?

Зареєструйтеся на Exercism, щоб вивчати й опановувати jq, а також 12 концепцій75 вправ та справжнє наставництво від людей, і все це безкоштовно.