Home > Enterprise >  How can I merge matching keys to into arrays via another key?
How can I merge matching keys to into arrays via another key?

Time:08-10

I have a GraphQL schema file with deeply nested object metadata that I'd like to extract into arrays of child properties. The original file is over 75000 lines long but I was able to successfully extract the Types & fields for each object using this command:

jq '.data.__schema.types[] | {name: .name, fields: .fields[]?.name?}' schema.json > output.json

Output:

{
  "name": "UsersConnection",
  "fields": "nodes"
}
{
  "name": "UsersConnection",
  "fields": "edges"
}
{
  "name": "UsersConnection",
  "fields": "pageInfo"
}
{
  "name": "UsersConnection",
  "fields": "totalCount"
}
{
  "name": "UsersEdge",
  "fields": "cursor"
}
{
  "name": "UsersEdge",
  "fields": "node"
}
...

But the output I want looks more like this:

[{
  "name": "UsersConnection",
  "fields": [ "nodes", "edges", "pageInfo", "totalCount" ]
},
{
  "name": "UsersEdge",
  "fields": [ "cursor", "node" ]
}]

I was able to do this by comma-separating each object, surrounding the output with { "data": [ -OUTPUT- ]} & the command:

jq 'map(. |= (group_by(.name) | map(first {fields: map(.fields)})))' output.json > output2.json

How can I do this with a single command?

CodePudding user response:

Assuming .data.__schema.types is an array, and so is .fields, you could try map in both cases:

.data.__schema.types | map({name: .name, fields: (.fields | map(.name))})

CodePudding user response:

I totally missed that I put the fields object inside brackets like this:

jq '.data.__schema.types[] | {name: .name, fields: [.fields[]?.name?]}'

Keeping this up for posterity in case someone else is trying to do the same thing

Update: I was able to get a cleaner, comma-separated result like this:

jq 'reduce .data.__schema.types[] as $d (null; .[$d.name] = [$d.fields[]?.name?])'

  • Related