代码之家  ›  专栏  ›  技术社区  ›  chx

使用jq重新格式化表格数据

jq
  •  0
  • chx  · 技术社区  · 1 年前

    我有一些JSON,其结构如下

    {
      "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"
            }
          ]
        }
    
    

    每行每列都有一个单元格,columnId与列中的id匹配。

    如何获得对象列表,如下所示:

    [
    {
      'column 1': 'foo',
      'column 2': 'bar'
    },
    {
      'column 1': 'foo1',
      'column 2': 'bar1'
    }
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   pmf    1 年前

    这是一种使用 INDEX JOIN 要执行匹配,一个 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


    这里有一个组合使用 索引 与@Glenn’s shorter approach map 这个 .cells 数组使用 string interpolation 要在映射中查找列id:

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

    Demo

        2
  •  1
  •   glenn jackman    1 年前

    这很管用,但很乱

    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"
      }
    ]