學習軌道
/
jq
jq
/
練習
/
購買車輛
購買車輛

購買車輛

學習練習

簡介

比較

比較數字

在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
Note

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

說明

在這個練習中,你會寫一些程式碼,幫助你為購買車輛做好準備。

你要完成三個任務:判斷自己是否需要取得駕照、在兩輛車之間做出選擇,以及估算一輛中古車的合理價格。

1. 判斷你是否需要駕照

有些種類的車輛需要有駕照才能操作。 假設只有"car"和"truck"這兩種需要駕照,其他種類都可以在沒有駕照的情況下操作。

實作needs_license函式,它接收車輛的種類,並回傳一個布林值,指出你需要駕照才能操作這種車輛。

"car" | needs_license
# => true

"bike" | needs_license
# => false

2. 在兩輛可能購買的車之間做出選擇

你已經評估過手邊可選的車輛。 你成功把選擇縮小到兩個,但還需要有人幫你做最後的決定。 實作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. 估算一輛中古車的價格

既然你已經做出決定,你會想確保自己在車商那裡拿到合理的價格。 因為你想買的是中古車,價格取決於車齡。 粗略估計的話,假設車齡不到 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
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
jq Exercism

準備好開始 購買車輛 了嗎?

註冊 Exercism,透過 12 個概念75 個練習 和真人引導來學習並精通 jq,全部免費。