首页 > 解决方案 > JQ 递归树扩展

问题描述

我正在尝试解析 JSON 结构以提取依赖路径,以便在自动化脚本中使用。

此 JSON 的结构被提取为如下格式:

[
  {
    "Id": "abc",
    "Dependencies": [
    ]
  },
  {
    "Id": "def",
    "Dependencies": [
      "abc"
    ]
  },
  {
    "Id": "ghi",
    "Dependencies": [
      "def"
    ]
  }
]

注意:删除了许多其他不相关的字段。

计划是能够将其中一个的 Id 传递给我的 JQ 命令并返回一个列表。

例如:

输入:abc
预期输出:[]

输入:def
预期输出:["abc"]

输入:ghi
预期输出:["abc", "def"]

目前有一个这样的 jq 脚本(https://jqplay.org/s/NAhuXNYXXO):

    jq 
    '. as $original | .[] | 
    select(.Id == "INPUTVARIABLE") | 
    [.Dependencies[]] as $level1Dep | [$original[] | select( [ .Id == $level1Dep[] ] | any )] as $level1Full | $level1Full[] | 
    [.Dependencies[]] as $level2Dep | [$original[] | select ( [ .Id == $level2Dep[] ] | any )] as $level2Full | 
    [$level1Dep[], $level2Dep[]]'

输入:abc
输出:空

输入:def 输出:["abc"]

输入:ghi 输出:["def","abc"]

伟大的!但是,正如您所看到的,这并不是特别可扩展的,并且只会处理两个依赖级别(https://jqplay.org/s/Zs0xIvJ2Zn),并且当一个项目有多个依赖项时(https : //jqplay.org/s/eB9zHQSH2r)。

有没有办法在 JQ 中构建它,还是我需要改用另一种语言?

标签: jsonrecursiondependenciesjq

解决方案


我知道数据不能具有循环依赖关系,它是从强制执行此操作的数据库中提取的。

那就微不足道了。将您的输入 JSON 简化为一个对象,其中每个 Id 和相应的 Dependencies 数组都配对,并使用递归函数遍历它聚合依赖项。

def deps($depdb; $id):
  def _deps($id): $depdb[$id] // empty
    | . + map(_deps(.)[]);
  _deps($id);
deps(map({(.Id): .Dependencies}) | add; $fid)

调用:

jq -c --arg fid 'ghi' -f prog.jq file

在线演示 - 任意依赖级别
在线演示 - 每个 Id 多个依赖项


推荐阅读