はじめに
AWS CLI の query で、パイプ(|)の挙動が分かりにくかったので整理した。
サンプルデータ
{
"foo": [
["one", "two"],
["three", "four"],
["five", "six"]
]
}
結論
プロジェクションfoo[*]
1に対し Index Expression(配列)でアクセスする場合、以下のように挙動が変わる。
-
foo[*][0]
["one", "three", "five"]
-
foo[*] | [0]
["one", "two"]
詳細
※https://jmespath.org/で実際にパスを入力しながら進めると、理解が早い。
前提: foo と foo[*]
foo
とfoo[*]
の結果は、両方とも以下のようになる。
[
["one", "two"],
["three", "four"],
["five", "six"]
]
foo[*][0]
foo[*][0]
は、foo[*]
で投影(projected)された各要素に対して[0]
でアクセスを行う。
foo[*]
は、配列fooの全ての子要素を投影
するため、子要素である["one", "two"]
, ["three", "four"]
, ["five", "six"]
が投影されている形になる。
つまり、上述したようにfoo[*]
の投影結果はfoo
と同様に以下のようになる。
しかし、foo
がこの 2 重配列全体を指しているのに対し、foo[*]
が投影しているのはそれぞれの子配列要素である。
(複数の配列要素を投影しているで、2 重配列として表現されているに過ぎない)
[
["one", "two"],
["three", "four"],
["five", "six"]
]
foo[*][0]
は、これら 3 つの配列要素の 0 番目の要素を 1 つの配列にマージする。
そのため、結果として["one", "three", "five"]
が投影される。
参考: Flatten Operator
foo[*] | [0]
|
(パイプ)を使用すると、投影された各要素を無視して、結果自体に右側の式を適用する。
foo[*] | [0]
は、以下のfoo[*]
の投影結果全体における 0 番目の要素を返す。
[
["one", "two"],
["three", "four"],
["five", "six"]
]
つまり、上の 2 重配列における 0 番目の要素である["one", "two"]
が返る
参考: Pipe Expressions
蛇足と言う名の応用
上記を踏まえた上で、 foo[*][0][0]
とfoo[*][0] | [0]
の結果がどう変わるか考えてみる。
上述したとおり、foo[*][0]
は以下の通り。
["one", "three", "five"]
答えはこちら
参考: Slices