【问题标题】:How to use fallback value when jq select() returns falsejq select()返回false时如何使用回退值
【发布时间】:2020-12-12 01:52:26
【问题描述】:

假设我有一个这样的 JSON 数组:

[
    {
        "name": "alpha",
        "value": 1
    },
    {
        "name": "beta",
        "value": 2
    },
    ...
]

(它包含大约 50-100 个项目;这是一个简化的示例。)

我想像这样从中生成一个 JSON 对象:

{
  "alpha": 1,
  "beta" 2,
  ...
}

认为它的 jq 过滤器看起来像这样:

.[] | { 
  "alpha": select(.name == "alpha") | .value,
  "beta": select(.name == "beta") | .value,
  ...
}

当我在https://jqplay.org/s/SOKd4oCh2k 上尝试时,这实际上不起作用,但我认为它非常接近。

好的,现在是棘手的部分:有时带有"name": "alpha"(或"name": "beta" 等)的对象实际上不会存在于输入数组中!在这种情况下,我想打印"alpha": null"alpha": ""。但我不知道如何将其集成到我的select() 电话中。

实际上,我需要它从批处理调度系统中抓取作业指标,在运行性能测试时我会随着时间的推移更改指标,因此对于特定作业运行,我查询的任何给定指标可能不存在,但我仍然想查看该作业运行的所有其他指标。

【问题讨论】:

    标签: json select jq default key-value


    【解决方案1】:

    该问题的 jq-esque 解决方案如下所示:

    jq 'from_entries | {alpha, beta, gamma}' input.json
    

    这会将数组转换为对象,然后选择与指定键对应的值(如果存在),同时确保所有指定键都存在。

    密钥列表

    如果你有一个键名的 JSON 数组(比如 $keylist),你可以这样写:

    from_entries as $in
    | reduce $keylist[] as $key ({}; .[$key]=$in[$key])
    
    

    后备值

    或者如果你想指定你自己的后备值,比如 $default:

    from_entries as $in
    | reduce $keylist[] as $key ({}; .[$key] = $in[$key] // $default)
    
    

    或者也许(取决于您的详细要求):

    from_entries as $in
    | reduce $keylist[] as $key ({};
        .[$key] = if ($in | has($key)) then $in[$key] else $default end)
    

    【讨论】:

    • 哇,太棒了,而且效果很好!非常感谢您的帮助!
    • 哦,我刚刚意识到from_entries 对我不起作用,因为我的字段实际上被命名为"metricName""doubleValue"不是 "name""value"。我会在我的问题中包含这个,但我认为具体的字段名称并不重要,所以我使用“名称”和“值”来使我的问题更通用......所以鉴于我不能使用 @ 987654331@,还有比这更 jq-esque 的解决方案吗? [.[] | { (.metricName): .doubleValue }] | add | {alpha, beta, gamma}
    • 关闭!更多 jq-esque 解决方案将使用 map: map( {(.metricName): .doubleValue} ) | add | {alpha,beta,gamma}
    • 太好了,谢谢!为我工作:jqplay.org/s/lQzCVY0xrA
    【解决方案2】:

    当然,在发布后,我就明白了。我想出的解决方案是使用add() 函数将对象数组扁平化为一个对象。

    所以这个过滤器:

    [.[] | { (.name): .value }] | add
    

    产生:

    {
      "alpha": 1,
      "beta": 2
    }
    

    然后选择我感兴趣的各个字段,这是基本的对象创建;例如| {alpha, beta, gamma}(输入数组中缺少“gamma”)产生:

    {
      "alpha": 1,
      "beta": 2,
      "gamma": null
    }
    

    如果有人想玩这个:https://jqplay.org/s/vqEYyGCg7W

    我会暂时搁置这个问题,以防有人有更好的解决方案!

    【讨论】:

      猜你喜欢
      • 2015-07-12
      • 2021-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多