使用 JQ 展平分层 JSON 数组

Posted

技术标签:

【中文标题】使用 JQ 展平分层 JSON 数组【英文标题】:Flatten a hierarchical JSON array using JQ 【发布时间】:2020-11-21 10:41:52 【问题描述】:

谁能帮我得到正确的 jq 命令来展平下面的例子?我看过其他一些帖子,我正在破解它,但似乎无法得到它。非常感谢任何帮助。

输入:

[
    
        "name": "level1",
        "children": [
            
                "name": "level2",
                "children": [
                    
                        "name": "level3-1",
                        "children": []
                    ,
                    
                        "name": "level3-2",
                        "children": []
                    
                ]
            
        ]
    
]

输出:

[
    
        "displayName": "level1",
        "parent": ""
    ,
    
        "displayName": "level2",
        "parent": "level1"
    ,
    
        "displayName": "level3-1",
        "parent": "level2"
    ,
    
        "displayName": "level3-2",
        "parent": "level2"
    
]

【问题讨论】:

【参考方案1】:

这是一个简单的解决方案,不涉及辅助函数,实际上解决了一个更普遍的问题。它基于这样的想法:首先为每个孩子添加一个“父”键,然后使用.. 收集所有名称/父对。

所以首先考虑:

[ walk(if type=="object" and has("children")
       then .name as $n | .children |= map(.parent = $n)
       else . end)
  | ..
  | select(type=="object" and has("name"))
  | displayName: .name, parent
]

这符合要求,除了对于***(无父)对象,它会生成一个 .parent 值null。这通常比“”更具有 JSON 风格,但如果确实需要空字符串,则只需将上面的最后一行替换为:

| displayName: .name, parent: (.parent // "")

【讨论】:

【参考方案2】:

用一个简单的递归函数:

def f: .name as $parent | .children[] | $parent, displayName: .name, f;
[ name: "", children: . | f ]

Online demo

【讨论】:

以上是关于使用 JQ 展平分层 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章

通过按键过滤数组,使用 jq 展平 JSON 文档

使用 Jq 展平 JSON,并在输出中使用数组索引

使用 jq 保留键名展平 JSON

如何使用 jq 展平复杂的 json 结构?

如何使用 jq 将任意简单 JSON 转换为 CSV?

使用 jq 展平嵌套的 JSON