skip to Main Content

I have some JSON with structure like

{
  "columns": [
    {
      "id": 123,
      "title": "column 1"
    },
    {
      "id": 456,
      "title": "column 2"
    }
  ],
  "rows": [
    {
      "cells": [
        {
          "columnId": 123,
          "value": "foo"
        },
        {
          "columnId": 456,
          "value": "bar"
        }
      ]
    },
    {
      "cells": [
        {
          "columnId": 123,
          "value": "foo1"
        },
        {
          "columnId": 456,
          "value": "bar1"
        }
      ]
    }

Each row has a cell for every column and columnId matches id in columns.

How could I get a list of objects looking like:

[
{
  'column 1': 'foo',
  'column 2': 'bar'
},
{
  'column 1': 'foo1',
  'column 2': 'bar1'
}

2

Answers


  1. This works, but it’s pretty messy

    jq '
      (.columns | map({(.id | tostring): .title}) | add) as $columnTitles
      | .rows | map(
          .cells | map({($columnTitles[.columnId | tostring]): .value}) | add
        )
    ' file.json
    
    [
      {
        "column 1": "foo",
        "column 2": "bar"
      },
      {
        "column 1": "foo1",
        "column 2": "bar1"
      }
    ]
    
    Login or Signup to reply.
  2. Here’s a way that uses INDEX and JOIN to perform the matching, one add to combine both sides of the match, and another add to create the final object (along with two other variants that each omit and compensate for an add).

    INDEX(.columns[]; .id) as $map | .rows | map(
      [JOIN($map; .cells[]; "(.columnId)"; add | {(.title): .value})] | add
    # [JOIN($map; .cells[]; "(.columnId)"; {(last.title): first.value})] | add
    # [JOIN($map; .cells[]; "(.columnId)"; add | .key = .title)] | from_entries
    )
    

    Demo
    Demo
    Demo


    And here’s one that combines using INDEX with @Glenn’s shorter approach to map the .cells array:

    INDEX(.columns[]; .id) as $map | .rows | map(
      .cells | map({($map."(.columnId)".title): .value}) | add
    )
    

    Demo

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