【问题标题】:Converting flat JSON into a nested JSON grouping by common key names通过常用键名将平面 JSON 转换为嵌套 JSON 分组
【发布时间】:2020-01-06 18:34:57
【问题描述】:

我正在使用 JQPlay 来播放该格式。我无法理解如何使用 reduce 来按子结构分组。我想根据组织或父 ID 进行分组。

只需更新我的 jqplay 过滤器,但无法删除两个标签以按 id 分组。

jq 播放语法-

我在 jqplay.org 中使用以下语法。也请您告知如何调试管道符号后的任何内容。

.items | {"org" : map( {id : .org, orgProperties : [{"properties" : {"methodId" : [{"id" : .methodId}]}}]})| group_by(.id) | map( reduce .[] as $x (.[0]|{}; .orgProperties+= ($x | .orgProperties)))}

输入 JSON

{
  "items": [
    {
      "org": "750141",
      "methodId": "1-10F7IAK7"
    },
    {
      "org": "750141",
      "methodId": "1-10TP18L0"
    },
    {
      "org": "750142",
      "methodId": "1-10TP18L1"
    }
  ]
}

输出 JSON

{
  "org": [
    {
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10F7IAK7"
              }
            ]
          }
        },
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10TP18L0"
              }
            ]
          }
        }
      ]
    },
    {
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10TP18L1"
              }
            ]
          }
        }
      ]
    }
  ]
}

预期的 JSON 输出

{
  "org": [
    {
      "id": "750141",
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10F7IAK7"
              },
              {
                "id": "1-10TP18L0"
              }
            ]
          }
        }
      ]
    },
        {
      "id": "750142",
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10TP18L1"
              }
            ]
          }
        }
      ]
    }
  ]
} 

【问题讨论】:

    标签: json jq


    【解决方案1】:

    您需要执行以下操作。你需要group_by()然后再做处理

    jq '.items | {org: group_by(.org) | map({id: .[0].org, orgProperties: [{properties: { methodId: map({id: .methodId}) }}]})} ' input.json
    

    我认为没有办法提高jq 抛出的调试详细级别,除非可能修改代码以添加您自己的调试语句并运行自定义构建。

    我个人一次从一个组件构建过滤器,观察其输出并在此基础上进行操作。分解上面的功能

    • 在过滤器的'.items | {org: .. 部分之后完全重建JSON。后续部分的结果形成了现在低于顶级 "org" 部分的预期输出。
    • 执行group_by(.org) 后,您会得到一个包含两个数组条目的结果,一个包含2 个对象(id 750141),另一个包含一个对象(id 750142)。
    • 然后你将map(..)里面的代码运行到上一步返回的对象列表中
    • 我们只需要最终结果中的唯一键名,所以我们只使用第一个数组中的.[0].org。即使您有多个重复的键名,这也将起作用。暂停并查看输出直到这一点

      {
        "org": [
          {
            "id": "750141"
          },
          {
            "id": "750142"
          }
        ]
      }
      
    • 现在用orgProperties: [{properties: { methodId: ... 构造其余的输出,它将子节点创建为

      "orgProperties": [
      {
          "properties": {
              "methodId": 
      
    • 使用map({id: .methodId})创建最终的子数组以创建带有ID列表的键值对

    【讨论】:

    • 谢谢伙计。它奏效了,很棒的是我明白它现在是如何完成的。但是你能解释一下为什么我们使用 .[0] ... 它意味着什么。
    • @user2993735:在group_by(.org)之后,创建了两个数组,第一个数组具有相同的值.org750141。所以我们通过使用.[0] 将这两者合二为一,这与.[1] 相同。查看.items | {org: group_by(.org)} 的输出并自己查看。
    猜你喜欢
    • 2017-11-22
    • 2022-11-29
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多