轨道
/
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。其他一切都是“真”,连数字 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

说明

在这个练习中,你将编写一些代码,帮助你为购买一辆车做准备。

共有三个任务:判断你是否需要取得驾照;在两辆车之间做出选择;以及估算一辆二手车可接受的价格。

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,全部免费。