skip to Main Content

Using jq, I’d like to to flatten a (nested) array of objects to an array of strings.

e.g. given the input

{
  "message-id": 1,
  "result": {
    "info": {
      "id": 1,
      "name": "foobar",
      "route": [
        {
          "nodeid": 1,
          "nodename": "name-1"
        },
        {
          "nodeid": 2,
          "nodename": "name-2"
        }
      ]
    }
  }
}

I’d like to turn it in to

{
  "name": "foobar",
  "route": [
    "name-1",
    "name-2"
  ]
}

But am struggling with flattening the route node – getting no further than
.result.info | {name: .name, route: .route} which essentially leaves the route node unchanged. This is probably straightforward, but nonetheless currently eluding me.

2

Answers


  1. It’s not entirely clear, what determines on which level you want to collect (e.g. you are using .result.info literally), and which fields to collect into (or why .id doesn’t get an empty array), but this might help you along your path:

    With .. you can recursively scan the document tree, strings filters for strings, and […] collects the results into an array. Also, I’ve used map_values to replace the values of all fields in the object. Feel free to change this to just the fields you need. You may, for instance, remove empty arrays or change one-item array to the one string itself.

    .result.info | map_values([.. | strings])
    
    {
      "id": [],
      "name": [
        "foobar"
      ],
      "route": [
        "name-1",
        "name-2"
      ]
    }
    

    Demo

    Login or Signup to reply.
  2. Here’s one way you could do it that’s pretty close to your attempt.

    .result.info
    | {name} + {route: .route|map(.nodename)}
    

    Example output:

    {
      "name": "foobar",
      "route": [
        "name-1",
        "name-2"
      ]
    }
    

    Try it on jqplay.org.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search