简体   繁体   English

使用 jq 根据输入中其他地方的值从数组中删除项目

[英]Using jq to remove items from an array based on values elsewhere in the input

I'm new to jq and trying to wrap my head around doing a few things that I thought were going to be straightforward.我是jq新手,并试图围绕做一些我认为很简单的事情。 Any ideas on how to improve this would be greatly appreciated.任何关于如何改进这一点的想法将不胜感激。

Given this input:鉴于此输入:

{
    "source": {
        "items": [
            { "id": "aaa", "name": "this" },
            { "id": "bbb", "name": "that" },
            { "id": "ccc", "name": "the other" }
        ]
    },
    "update": {
        "toRemove": [
            "aaa",
            "ccc"
        ]
    }
}

I want this result:我想要这个结果:

{
    "items": [
        { "id": "bbb", "name": "that" }
    ]
}

This filter does the job but the variables lead me to believe there is a cleaner way.这个过滤器可以完成这项工作,但变量让我相信有一种更清洁的方法。

. as $root | .source + { items: [.source.items[] | select(.id as $id | $root.update.toRemove | contains([$id]) | not)]}

Playground link if interested: https://jqplay.org/s/GpVJfbTO-Q如果有兴趣,游乐场链接: https : //jqplay.org/s/GpVJfbTO-Q

Here's a concise and efficient solution: 这是一个简洁而有效的解决方案:

.update.toRemove as $rm
| .source
| .items |= map( select(.id | IN($rm[]) | not))

A little shorter version using inside instead of contains : 使用inside而不是contains更短的版本:

.update.toRemove as $temp |
 {items: [.source.items[] | select([.id] | inside($temp) | not)]}

and an alternative solution, using jtc 和另一种解决方案,使用jtc

bash $ <input.json jtc -w'<items>l[-1]' | jtc -w'[id]:<bbb>[-1]' -pp
{
   "items": [
      {
         "id": "bbb",
         "name": "that"
      }
   ]
}
bash $ 

first jtc statement prints items entirely, second removes everything except object with bbb 第一个jtc语句完全打印items ,第二个删除除了bbb对象以外的所有内容

* UPDATE * latest version of jtc allows now namespaces. * UPDATE *最新版本的jtc现在允许名称空间。 To facilitate the ask, use it like this: 为方便询问,请使用如下:

bash $ <input.json jtc -w'[update][toRemove][:]<2rm>v [^0][id]:<2rm>s[-1]' -p | jtc -w'[source]'
{
   "items": [
      {
         "id": "bbb",
         "name": "that"
      }
   ]
}
bash $ 

Explanations: 说明:

1. [update][toRemove][:]<2rm>v - that portion of a walk-path will iterate over each item in toRemove while storing each iterated value in the namespace 2rm 1. [update][toRemove][:]<2rm>v - 步行路径的那一部分将迭代toRemove每个项目,同时将每个迭代值存储在命名空间2rm

2. [^0][id]:<2rm>s[-1] - will reset the walk-path back to root ( [^0] ) and find each JSON entry matching one stored in 2rm , [-1] will select a parent of the found entry (which selects the item record 2. [^0][id]:<2rm>s[-1] - 将步行路径重置回root( [^0] )并找到与2rm存储的匹配的每个JSON条目, [-1]选择找到的条目的父级(选择项目记录

3. -p will purge the found (walked) elements and next jtc will select the source 3. -p将清除找到的(走过的)元素,然后jtc将选择source

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM