jq で複数の「オブジェクトの配列」をマージする

jq でオブジェクトの配列を上手くマージする方法。jq は複数の配列を結合したり色々出来るのだが、分かりにくいのでやりたいことをまとめておく。

今回は次のような3つのファイルがあって、各オブジェクトの id プロパティを使ってデータを結合したいとする。

$ cat << EOL > list1.json
[
  { "id": "aaa", "name": "AAA" },
  { "id": "bbb", "name": "BBB" }
]
EOL

$ cat << EOL > list2.json
[
  { "id": "aaa", "age": 25 },
  { "id": "bbb", "age": 19 }
]
EOL

$ cat << EOL > list3.json
[
  { "id": "aaa", "gender": "Male"   },
  { "id": "bbb", "gender": "Female" }
]
EOL

以下のように flatten して group_by して mapreduce する。ワケワカラン。w

$ jq -s 'flatten | group_by(.id) | map(reduce .[] as $x ({}; . * $x))' list1.json list2.json list3.json
[
  {
    "id": "aaa",
    "name": "AAA",
    "age": 25,
    "gender": "Male"
  },
  {
    "id": "bbb",
    "name": "BBB",
    "age": 19,
    "gender": "Female"
  }
]

おしり。