キーごとに値を配列として収集する方法は?

キーごとに値を配列として収集する方法は?

重複キーを使用して、指定された入力形式で入力します。

[
  {"key": "a", "value": 0},
  {"key": "a", "value": 1},
  {"key": "a", "value": 2},
  {"key": "b", "value": 3},
  {"key": "b", "value": 4},
  {"key": "b", "value": 5}
]

生産したい

{"a": [0, 1, 2], "b": [3, 4, 5]}

つまり、各一意のキーについて、同じキーを持つすべての値が配列に収集されます。

どうすればいいですかjq

ベストアンサー1

reduce()値として提供されたキーに指定された値を追加して結果オブジェクトを徐々に構築するには、inを使用しますjqvaluekey

$ jq -c 'reduce .[] as $a ({}; .[$a.key] += [$a.value])' file
{"a":[0,1,2],"b":[3,4,5]}

これはreduce()ループのように動作します。この場合、.[]最上位配列のすべてのオブジェクトを繰り返します。各オブジェクトについて、キーの下の結果オブジェクト(最初は空のオブジェクト)$aに値が追加されます。$a.value{}$a.key


使用を好む人のための追加のヒントjq: を使用すると、debug式の実行中に式の任意の時点でデータを表示できます。ここでは、ループの各反復後にアキュムレータオブジェクトの状態を調べますreduce()

$ jq -c 'reduce .[] as $a ({}; .[$a.key] += [$a.value] | debug)' file
["DEBUG:",{"a":[0]}]
["DEBUG:",{"a":[0,1]}]
["DEBUG:",{"a":[0,1,2]}]
["DEBUG:",{"a":[0,1,2],"b":[3]}]
["DEBUG:",{"a":[0,1,2],"b":[3,4]}]
["DEBUG:",{"a":[0,1,2],"b":[3,4,5]}]
{"a":[0,1,2],"b":[3,4,5]}

$aここでは、各反復に割り当てられた値を見てみましょう。

$ jq -c 'reduce (.[]|debug) as $a ({}; .[$a.key] += [$a.value])' file
["DEBUG:",{"key":"a","value":0}]
["DEBUG:",{"key":"a","value":1}]
["DEBUG:",{"key":"a","value":2}]
["DEBUG:",{"key":"b","value":3}]
["DEBUG:",{"key":"b","value":4}]
["DEBUG:",{"key":"b","value":5}]
{"a":[0,1,2],"b":[3,4,5]}

おすすめ記事