【问题标题】:Select items in array based on a property value根据属性值选择数组中的项目
【发布时间】:2020-05-25 17:37:15
【问题描述】:

作为开发人员,当我使用以下 JQ 命令时:

.first_level."second_level"[] |= select(.fruit == "pear")

我将它应用到这个 JSON:

{
  "first_level": {
    "second_level": [
      {
        "fruit": "apple"
      },
      {
        "fruit": "pear"
      },
      {
        "fruit": "banana"
      },
      {
        "fruit": "donuts"
      }
    ]
  }

}

然后我想要这个输出(只保留属性fruit等于pear的项目):

{
  "first_level": {
    "second_level": [
      {
        "fruit": "pear"
      }
    ]
  }

}

但是当前返回的值是(也可以看JQ Playhere):

{
  "first_level": {
    "second_level": [
      {
        "fruit": "pear"
      },
      {
        "fruit": "donuts"
      }
    ]
  }
}

--> 它使用 donuts 保留值,我不明白的是,从 JQ 文档中,|= 应该分配选择的值,但是在运行时:

.first_level."second_level"[] |选择(.fruit == "梨")

我有以下结果:

{
  "fruit": "pear"
}

--> 似乎选择成功,但做作并没有像我预期的那样表现(它添加了donuts)。

对于此问题的任何帮助将不胜感激。提前致谢! :)

【问题讨论】:

  • .first_level."second_level"[] |选择(.fruit == “梨”)

标签: json select jq


【解决方案1】:

鉴于您的示例输入,该程序所做的基本上是这样的:

.first_level.second_level |= (
    delpaths([[0]]) # apple != pear
  | delpaths([[1]]) # banana != pear
  | delpaths([[2]]) # null != pear
  | delpaths([[3]]) # null != pear
)

查看|= 的底层内置函数here 是如何实现的;当|= 的右侧应用于路径值时,如果结果为empty,则通过delpaths 删除该路径。那么问题就清楚了,当.[0](苹果)被删除时,.[1](梨)就变成了.[0];但是_modify 没有考虑到该更改,因为它会在开始时将要修改的路径列表考虑一次并且不会再次更新,并继续使用.[1](香蕉)。

您可以改用这个:

del(.first_level.second_level[] | select(.fruit != "pear"))

或者如果你坚持涉及|=的解决方案:

.first_level.second_level |= map(select(.fruit == "pear"))

【讨论】:

  • 谢谢!我现在明白为什么这段代码的行为不像我预期的那样。非常感谢您提供的澄清和样品! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2019-12-03
相关资源
最近更新 更多