在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.
上述的比較運算子也可以用來比較字串。 這種情況下,會套用字典(詞典)順序。 排序的依據是_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
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."
既然你已經做出決定,你會想確保自己在車商那裡拿到合理的價格。 因為你想買的是中古車,價格取決於車齡。 粗略估計的話,假設車齡不到 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