【问题标题】:Is the jq + operator eager?jq + 运算符是否渴望?
【发布时间】:2020-11-07 23:02:13
【问题描述】:

我最初将我的 jq 命令写为

.data.viewer.zones[] | .httpRequests1mGroups[0].sum|with_entries(select(.key|endswith("Map")|not))  + {"zoneTag": .zoneTag} 

得到了这个结果:

{
  "bytes": 2875120330,
  "cachedBytes": 1475518778,
  "zoneTag": null
}
{
  "bytes": 2875120330,
  "cachedBytes": 1475518778,
  "zoneTag": null
}

zoneTagzones 对象中的最后一个属性。

我把命令改写为

.data.viewer.zones[] |  {"zoneTag": .zoneTag} +   .httpRequests1mGroups[0].sum|with_entries(select(.key|endswith("Map")|not))  

得到我所期望的:

{
  "zoneTag": "zone 1",
  "bytes": 2875120330,
  "cachedBytes": 1475518778,
}
{
  "zoneTag": "zone 2",
  "bytes": 2875120330,
  "cachedBytes": 1475518778,
}

我的问题是为什么? + 渴望吗? (我使用* 得到了相同的结果。)

谢谢。

【问题讨论】:

    标签: jq operator-precedence


    【解决方案1】:

    所以也许您正在寻找关于运算符优先级的解释。

    让:

    A代表.data.viewer.zones[]

    B代表.httpRequests1mGroups[0].sum

    C代表with_entries(select(.key|endswith("Map")|not))

    那么你的第一个 jq 表达式就相当于

    A | B | C + {zoneTag}
    

    而你的第二个相当于:

    A  | {zoneTag} + B | C
    

    所以在第一种情况下,{zoneTag} 从 B 获取其值,但在 第二种情况,它来自A。

    【讨论】:

      【解决方案2】:

      在 jq 中,对于大多数目的,包括对象添加的目的,右侧对象中的显式空值与缺少键是不同的。

      因此如果 A 是 {"a": 1} 那么 A + {} 是 A 但 A + {"a": null} 是 {"a": null}。

      因此,“最右边的值”规则必须理解为“最右边的显式值”。

      这是否与“渴望”有关取决于您对该术语的理解。

      非惰性求值

      在 jq 中,对象添加(实际上是一般添加)从右到左进行,当然是非惰性的,如下例所示,这也说明了上面提到的 RHS 优势。

      jq -n '{a:(1|debug)} + {b: (2|debug)} + {a:(3|debug)}'
      ["DEBUG:",3]
      ["DEBUG:",2]
      ["DEBUG:",1]
      {
        "a": 3,
        "b": 2
      }
      

      但据我所知,可能无法保证右关联性。

      【讨论】:

      • 嗯。谢谢。所以这不是 RE 意义上的渴望,但这并不能解释为什么 zoneTag 在右边时为空 - 还是这样?
      • 我知道在 RE 和一般评估的背景下,热切指的是什么。 jq 添加显然不是“懒惰的”,但我不确定这有什么相关性。如果 jq 具有用于添加对象的短路语义,那将是相关的,但它没有。
      • 所以让我们忘记急切和懒惰,为什么zoneTag 捕获在+ 右侧失败?
      猜你喜欢
      • 2014-10-28
      • 1970-01-01
      • 2013-05-06
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多