JQ:修改作为过滤器结果的对象,同时保持原始结构

JQ: Modify object that is the result of a filter while keeping the original structure

我有以下JSON

原始数据

{
  "myValues": [
    {
      "filterableValue": "x",
      "something": "else"
    },
    {
      "filterableValue": "y",
      "another key": "another value"
    },
    {
      "filterableValue": "z"
    }
  ],
  "foo": "bar"
}

使用 JQ,我想将一个键值对添加到 myValues 数组中的第一个(或所有)条目,它们具有 filterableValue=="y"myValues 数组中这些条目的 position/index 是任意的。

预期输出

结果应具有相同的结构(仍包含 foomyValues)但具有修改后的条目,其中 filterableValue=="y".

{
  "myValues": [
    {
      "filterableValue": "x",
      "something": "else"
    },
    {
      "filterableValue": "y",
      "another key": "another value",
      "this": "has been added" // <-- this is the only thing that changed
    },
    {
      "filterableValue": "z"
    }
  ],
  "foo": "bar"
}

我尝试过的方法以及失败的原因

到目前为止,我设法过滤了相应的数组条目并在过滤后的输出上设置了值,但没有设法保持原始结构并修改过滤后的条目。 添加 "this":"has been added" 对但 包含原始结构的我的 JQ 是:

.myValues|map(select(.filterableValue=="y"))[0]|.this="has been added" jqplay mwe

问题

如何修改过滤后的条目,如上包含原始结构?

将 LHS 上的整个选择器括在括号内:

(.myValues[] | select(.filterableValue == "y")).this = "has been added"

Demo

首先,让我们清理一下

.myValues | map(select(.filterableValue=="y"))[0]

最好写成

.myValues[] | select(.filterableValue=="y")

它不仅更短,而且可以更好地处理有 0 或 2+ 个匹配项的情况。


那么,你只需要把... |改成( ... ) |=即可。

( .myValues[] | select(.filterableValue=="y") ) |= ( .this = "has been added" )

Demo