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
数値が入っているように見えても型が文字列である2つの変数を比較するときは、注意が必要です。 辞書順のため、結果は数値型の値を比較した場合と同じにはなりません。
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.
2つの配列は、対応するすべての要素が等しければ等しいとみなされます。
[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
2つのオブジェクトは、同じキーと値のペアを持っていれば等しいとみなされます。
{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節は省略可能です。次の2つの文は等価です。
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
代替演算子を使うと、式が偽または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
この演習では、乗り物の購入準備に役立つコードを書いていきます。
やることは3つあります。免許が必要かどうかを判断すること、2台の乗り物から1台を選ぶこと、そして中古の乗り物の妥当な価格を見積もることです。
乗り物の種類によっては、運転するのに運転免許証が必要です。
"car"と"truck"の2種類だけが免許を必要とし、それ以外は免許なしで運転できるものとします。
乗り物の種類を受け取り、その種類に免許が必要かどうかを示す真偽値を返すneeds_license関数を実装してください。
"car" | needs_license
# => true
"bike" | needs_license
# => false
買える乗り物の候補を検討した結果、2台まで絞り込めましたが、最終的な判断には助けが必要です。
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年未満なら、新車だったときの元の価格の80%になります。 10年を超えていれば50%です。 3年以上10年以下なら、元の価格の70%になります。
if、elif、elseを使ってこのロジックを適用するresell_price関数を実装してください。
元の価格と乗り物の年数を持つオブジェクトを受け取り、ディーラーでの見積もり価格を返します。
{"original_price": 1000, "age": 1} | resell_price
# => 800
{"original_price": 1000, "age": 5} | resell_price
# => 700
{"original_price": 1000, "age": 15} | resell_price
# => 500