如何按其他数组中的值过滤元素

How to filter elements by values from another arrays

提问人:Maxim Suslov 提问时间:11/17/2023 最后编辑:Maxim Suslov 更新时间:11/17/2023 访问量:71

问:

我有以下JSON数据:

{
    "services": [
        {
            "name": "B1",
            "criticality": "BC"
        },
        {
            "name": "B2",
            "criticality": "BC"
        },
        {
            "name": "M1",
            "criticality": "MC"
        },
        {
            "name": "M2",
            "criticality": "MC"
        },
        {
            "name": "M3",
            "criticality": "MC"
        },
        {
            "name": "M4",
            "criticality": "MC"
        }
    ],
    "links": [
        {
            "from_name": "B1",
            "to_name": "M1"
        },
        {
            "from_name": "M1",
            "to_name": "M2"
        },
        {
            "from_name": "M2",
            "to_name": "B2"
        },
        {
            "from_name": "M1",
            "to_name": "M3"
        },
        {
            "from_name": "M4",
            "to_name": "M2"
        }
    ]
}

我想找到那些拥有并依赖其他服务的服务。criticality==MCcriticality==MC

输出可能如下所示: 服务及其依赖项

{
  "M1": [
    "M2",
    "M3"
  ],
  "M4": [
    "M2"
  ]
}

(它可以是一个数组而不是列表)

怎么做?


当我深入研究链接时,我丢失了有关服务的信息,反之亦然:

.links[] as $in | .services.[] | select(.name == $in.from_name) | select(.criticality == "MC")

将产生:

{
  "name": "M1",
  "criticality": "MC"
}
{
  "name": "M2",
  "criticality": "MC"
}

但是没有关于..links

JQ型

评论

1赞 pmf 11/17/2023
两个问题:(1) 在您的示例输出中(除了不是有效的 JSON),为什么 M2 没有列在顶级上?(2) 您是否要递归跟踪依赖项,如果是这样,那么输出会是什么样子?例如,如果 B2 也有 MC,并且 M2 依赖于 B2,而 M1 依赖于 M2,这将如何在输出中表示(如果您想深入挖掘不止一层)?
0赞 Maxim Suslov 11/17/2023
@pmf:(1) M2 未列出,因为它没有 .to_name 服务有的链接。只。criticality=MCBC
0赞 Maxim Suslov 11/17/2023
@pmf:(2)不需要递归依赖。但是,如果有可能看到一个替代解决方案,可以检测从 MC 到任何其他 MC 的所有间接依赖关系,那就太好了!
0赞 Maxim Suslov 11/17/2023
@pmf:修复了有效 JSON 的答案。它是一个映射数组(key 是服务名称,value 是其依赖项的数组)。谢谢,提到的错误。
0赞 Inian 11/17/2023
您能否分享另一个具有多个依赖项的示例,即 , ?M2M3

答:

1赞 Maxim Suslov 11/17/2023 #1

我的解决方案是:

# find the MC services and put them into $mc
[ .services[] | select(.criticality == "MC") | .name ] as $mc | 

# filter links by having MC only in source and target
[ .links[] | select(.from_name | IN($mc[])) | select(.to_name | IN($mc[])) ] |

# group results by .from_name
group_by(.from_name) | map({(.[0].from_name):map(.to_name)}) | add

在线查询: https://jqplay.org/s/AwFt0Ke7DLO