json - 将平面 JSON 转换为按公共(public)键名分组的嵌套 JSON

标签 json jq

我使用 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"
              }
            ]
          }
        }
      ]
    }
  ]
} 

最佳答案

您需要执行如下操作。您需要 group_by() 然后再进行处理

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

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

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

  • '.items | 之后完全重构 JSON {org: .. 过滤器的一部分。后续部分的结果构成了现在位于顶级 “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 列表创建键值对

关于json - 将平面 JSON 转换为按公共(public)键名分组的嵌套 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59605183/

相关文章:

javascript - 获取 JSON 值的总计

javascript - 数组中的 JSON 对象数组在 javascript 中查找和替换

java - 通过类名反序列化json

JSON API结果格式

.net - 将 JSON 字符串反序列化为 VB.net 对象

json - 有什么方法可以覆盖或更新 Jersey 的 Jackson 版本吗?

json - 使用 jq 返回多个元素?

linux - 在 shell 脚本中转义 jq 表达式中的符号

json - JQ 删除多个属性

jq 不适用于包含来自变量的破折号的键