در jq میتوان اعداد را با عملگرهای رابطهای و برابری زیر مقایسه کرد.
| مقایسه | عملگر |
|---|---|
| بزرگتر از | a > b |
| بزرگتر یا مساوی | a >= b |
| کوچکتر از | a < b |
| کوچکتر یا مساوی | a <= b |
| مساوی | a == b |
| نامساوی | a != b |
نتیجهی مقایسه همیشه یک مقدار منطقی است، یعنی یا 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.
از عملگرهای مقایسهی بالا میتوان برای مقایسهی رشتهها هم استفاده کرد. در این حالت، ترتیبی واژهنامهای (لغتنامهای) اعمال میشود. این ترتیب بر اساس مقدار کدپوینت یونیکد است.
"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
if تودرتوبا 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
عملگر جایگزین به شما امکان میدهد در صورتی که یک عبارت false یا 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 را پیادهسازی کنید که نوع خودرو را میگیرد و یک مقدار «منطقی» برمیگرداند که نشان میدهد آیا برای آن نوع خودرو به گواهینامه نیاز دارید یا نه.
"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."
حالا که تصمیمتان را گرفتهاید، میخواهید مطمئن شوید که در نمایندگی خودرو را با قیمت منصفانه میخرید. چون میخواهید یک خودروی دستدوم بخرید، قیمت به سن خودرو بستگی دارد. برای یک تخمین تقریبی، فرض کنید اگر خودرو کمتر از ۳ سال سن داشته باشد، قیمتش ۸۰٪ قیمت اصلی آن هنگام نو بودن است. اگر بیش از ۱۰ سال سن داشته باشد، ۵۰٪. اگر خودرو حداقل ۳ سال سن داشته باشد اما بیشتر از ۱۰ سال نباشد، ۷۰٪ قیمت اصلی است.
تابع 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