JSONでは、配列を次のように定義しています。
配列とは、順序付けられた値の集まりです。 配列は左角括弧
[で始まり、右角括弧]で終わります。 値はカンマ,で区切られます。
配列には、JSONの値ならどのような種類でも、0個以上入れることができます。 配列の要素は、すべてが同じ型である必要はありません。
角括弧([])を使うと、要素をまとめて配列にできます。
[1, 2, 3]
ストリームの要素は、角括弧で囲むと配列にまとめられます。
range(5) # => a stream of 5 numbers
[range(5)] # => the array [0, 1, 2, 3, 4]
length関数は、配列の要素数を返します。
配列のインデックスは0から始まります。
角括弧を使った式で、配列から要素を取り出せます。
.[2]は3番目の要素を取得します。
負のインデックスは、配列の末尾から逆に数えます。
.[-1]は最後の要素、.[-2]は後ろから2番目の要素です。
スライスとは、配列の一部を切り出したものです。
.[10:15]は、インデックス10から始まる5つの要素を返します。終了インデックスは含まれません。
便利な関数もいくつかあります。
firstは最初の要素を取得します。lastは最後の要素を取得します。nth(n)はインデックスnの要素を取得します。配列の要素を1つずつストリームにしたい場面があります。
そんなときは.[]を使います。
配列に入っている文字列の長さを、ストリームとして取り出したいとしましょう。
["a", "be", "cat", "door"] | length # => 4 -- the number of elements in the array
["a", "be", "cat", "door"] | .[] | length # => 1, 2, 3, 4 -- the lengths of each element
空の角括弧は、パイプを省略して前の式のすぐ横に置くこともできます。
["a", "be", "cat", "door"][] | length # => 1, 2, 3, 4 -- the lengths of each element
# ........................^^
配列を連結するには+を使います。
[1, 2, 3] + [4, 5] # => [1, 2, 3, 4, 5]
-演算子は、右側の配列の要素を、左側の配列から取り除きます。
[range(10)] - [2, 4, 6] # => [0, 1, 3, 5, 7, 8, 9]
jqには、よくある繰り返し処理に対応するための関数がたくさん用意されています。
map(expr)は、各要素に順番にexprを適用した新しい配列を返します。
[1, 2, 3] | map(. * 10) # => [10, 20, 30]
select(expr)は、1つの値にexprを適用する関数です。
式の結果がtrueなら、その値が返されます。
結果がfalseなら、何も返されません。nullではなく、本当に何も返らないのです。
これを配列に対して使うには、mapと組み合わせます。
[range(10)] | map(select(. % 2 == 0)) # => [0, 2, 4, 6, 8]
もう1つの方法として、ストリームにselectを適用し、その結果をまとめるやり方もあります。
[range(10) | select(. % 2 == 0)] # => [0, 2, 4, 6, 8]
any(condition)とall(condition)は、配列の要素の中に条件を満たすものが1つでもあるか、すべてが満たすかを、真偽値で返します。
[1, 2, 3, 4] | any(. > 4) # false
[1, 2, 3, 4] | any(. >= 4) # true
[1, 2, 3, 4] | all(. >= 4) # false
[1, 2, 3, 4] | all(. <= 4) # true
配列に要素が含まれているかどうかは、indexで調べられます。
この関数は、指定した要素が配列にあればそのインデックスを返し、なければnullを返します。
["carrots", "beef", "potatoes"] | index("beef") # => 1
["carrots", "beef", "potatoes"] | index("bees") # => null
逆の働きをするINという関数もあります(そう、大文字です)。
INのやっかいな点は、引数が配列ではなくストリームであることです。
"beef" | IN(["carrots", "beef", "potatoes"][]) # => true
"bees" | IN(["carrots", "beef", "potatoes"][]) # => false
Rubyには、要素の値とそのインデックスをペアにする便利なeach_with_indexメソッドがあります。
Pythonにはenumerateがあります。
jqにもよく似たto_entriesという関数があります。
これは配列を、{key: index, value: value}というオブジェクトの配列に変換します。
[11, 22, 33, 44] | to_entries
# => [{key: 0, value: 11}, {key: 1, value: 22}, {key: 2, value: 33}, {key: 3, value: 44}]
sortとsort_by
group_by
min、max、min_by、max_by
unique、unique_by
flatten