У jq числа можна порівнювати за допомогою таких операторів відношення та рівності.
| Порівняння | Оператор |
|---|---|
| Більше ніж | a > b |
| Більше або дорівнює | a >= b |
| Менше ніж | a < b |
| Менше або дорівнює | a <= b |
| Дорівнює | a == b |
| Не дорівнює | a != b |
Результат порівняння завжди є булевим значенням (англ. Boolean), тобто або true, або false.
1 < 3, # => true
2 != 2, # => false
1 == 1.0 # => true
# All numbers are floating-points, so this is different syntax
# for the exact same value.
Оператори порівняння вище можна також використовувати для порівняння рядків тексту (англ. string). У цьому разі застосовується словниковий (лексикографічний) порядок. Порядок визначається значенням коду символу Unicode.
"Apple" > "Pear", # => false
"a" < "above", # => true
"a" == "A" # => false
Треба бути уважними, коли ми порівнюємо дві змінні, які, на перший погляд, містять числові значення, але насправді є рядками тексту. Через словниковий порядок результат буде не таким, як під час порівняння значень типу число.
10 < 2, # => false
"10" < "2" # => true (because "1" comes before "2")
Оператор == у jq схожий на === у JavaScript у тому сенсі, що речі, які мають однаковий вигляд, але належать до різних типів, не є рівними.
"3" == 3 # => false
# the value on the left has type string,
# the value on the right has type number.
Два масиви рівні, якщо всі відповідні елементи рівні.
[1, 2, 3] == [1, 2, 3] # => true
[1, 2, 3] == [1, 3, 2] # => false, different order
[1, 2, 3] == [1, 2, "3"] # => false, different types
Два обʼєкти рівні, якщо вони мають однакові пари ключ-значення.
{name: "Joe", age: 42} == {age: 42, name: "Joe"} # => true
{name: "Joe", age: 42} == {age: 42, name: "Jane"} # => false
{name: "Joe", age: 42} == {age: "42", name: "Joe"} # => false
{name: "Joe", age: 42} == {age: 42, name: "Joe", height: 175} # => false
# comparisons will drill down as deeply as required
{a: {b: {c: [1, 2]}}} == {a: {b: {c: [1, 2]}}} # => true
{a: {b: {c: [1, 2]}}} == {a: {b: {c: [1, 2, 3]}}} # => false
if
Умовний вираз у jq має такий вигляд: if A then B else C end.
if-then-else - це фільтр, як і всі вбудовані функції jq: він приймає вхідні дані та видає вихідні дані.
Якщо вираз A дає «правдиве» значення, то фільтр if обчислює B.
Інакше він обчислює C.
Вхідні дані фільтра if буде передано до B або C.
42 | if . < 50 then "small" else "big" end # => "small"
5 | if . % 2 == 0 then . / 2 else . * 4 end # => 20
Блок else є необовʼязковим; наведені нижче дві інструкції рівнозначні.
if A then B else . end
if A then B end
Додаткові умови можна додавати за допомогою elif.
42 | if . < 33 then "small"
elif . < 66 then "medium"
else "big"
end
# => "medium"
Можна використати стільки блоків elif, скільки потрібно.
Єдині «неправдиві» значення в jq - це false і null.
Усе інше є «правдивим», навіть число нуль і порожній рядок тексту, масив та обʼєкт.
Булеві оператори and та or можна використовувати для побудови складних запитів.
42 | if . < 33 or . > 66 then "big or small"
else "medium"
end
Щоб заперечити, можна скористатися not. Це фільтр, а не оператор.
42 | if (. < 33 or . > 66 | not) then "medium"
else "big or small"
end
Оператор альтернативи дає змогу вказати «типове» значення, якщо вираз є неправдивим або null.
A // B
# This is identical to
if A then A else B end
Для прикладу
[3, 5, 18] | add / 2 # => 13
[] | add / 2 # => error: null (null) and number (2) cannot be divided
[] | add // 0 / 2 # => 0
У цій вправі ми напишемо трохи коду, який допоможе підготуватися до купівлі транспортного засобу.
На нас чекають три завдання: визначити, чи потрібне посвідчення водія; обрати один із двох транспортних засобів; та оцінити прийнятну ціну вживаного транспортного засобу.
Деякі види транспортних засобів потребують посвідчення водія для керування ними.
Вважаємо, що посвідчення водія потребують лише види "car" і "truck"; усім іншим можна керувати без нього.
Реалізуйте функцію needs_license, яка приймає вид транспортного засобу й повертає булеве значення (англ. Boolean), що вказує, чи потрібне посвідчення водія для цього виду транспортного засобу.
"car" | needs_license
# => true
"bike" | needs_license
# => false
Ми вже оцінили доступні варіанти транспортних засобів.
Нам вдалося звузити вибір до двох варіантів, але потрібна допомога, щоб ухвалити остаточне рішення.
Реалізуйте функцію choose_vehicle, яка приймає масив із двох транспортних засобів і повертає рішення, тобто варіант, що йде першим за словниковим порядком.
["Wuling Hongguang", "Toyota Corolla"] | choose_vehicle
# => "Toyota Corolla is clearly the better choice."
["Volkswagen Beetle", "Volkswagen Golf"] | choose_vehicle
# => "Volkswagen Beetle is clearly the better choice."
Тепер, коли рішення ухвалено, ми хочемо бути впевнені, що отримаємо справедливу ціну в автосалоні. Оскільки нас цікавить купівля вживаного транспортного засобу, ціна залежить від його віку. Для приблизної оцінки вважаємо, що якщо транспортному засобу менше ніж 3 роки, він коштує 80% початкової ціни, яку мав, коли був новим. Якщо йому понад 10 років, він коштує 50%. Якщо транспортному засобу щонайменше 3 роки, але не більше ніж 10 років, він коштує 70% початкової ціни.
Реалізуйте функцію resell_price, яка застосовує цю логіку за допомогою if, elif та else.
Вона приймає обʼєкт із початковою ціною та віком транспортного засобу і повертає приблизну ціну в автосалоні.
{"original_price": 1000, "age": 1} | resell_price
# => 800
{"original_price": 1000, "age": 5} | resell_price
# => 700
{"original_price": 1000, "age": 15} | resell_price
# => 500
Зареєструйтеся на Exercism, щоб вивчати й опановувати jq, а також 12 концепцій75 вправ та справжнє наставництво від людей, і все це безкоштовно.