jq flatten list of objects into one object

Viewed 141

I want to go from

[
  {"key_skjdghkbs": "deep house"},
  {"key_kjsskjbgs": "deadmau5"},
  {"key_jhw98w4hl": "progressive house"},
  {"key_sjkh348vg": "swedish house mafia"},
  {"key_js3485jwh": "dubstep"},
  {"key_jsg587jhs": "escape"}
]

to

{
  "key_skjdghkbs": "deep house",
  "key_kjsskjbgs": "deadmau5"
  "key_jhw98w4hl": "progressive house",
  "key_sjkh348vg": "swedish house mafia",
  "key_js3485jwh": "dubstep",
  "key_jsg587jhs": "escape"
}

Each object in the original list has exactly one key but the keys are unique.

I could do something like jq .[] .genre if the keys were the same but they're not.

3 Answers

Try this (assuming your file is named so72297039.json):

jq '[.[] | to_entries] | flatten | from_entries' < so72297039.json

(Edit: OP edited question, so here's relevant answer)

Since duplicate keys are not possible (see other answer) you can use to format like this:

{
  "artist": [
    "deadmau5",
    "swedish house mafia"
  ],
  "genre": [
    "deep house",
    "progressive house",
    "dubstep"
  ],
  "song": [
    "escape"
  ]
}

with a jq call like this:

jq '
    map(to_entries)
    | flatten
    | group_by(.key)
    | map({key: first.key, value: map(.value)})
    | from_entries
' input.json

If the keys artist, genre, song are known in advance an easier to understand expression can be used.

Related