在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
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。其他一切都是“真”,连数字 0、空字符串、空数组和空对象也不例外。
可以用布尔运算符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 函数,它接收车辆类型,并返回一个布尔值,表示该类型的车辆是否需要驾照。
"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