はじめに
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