首页 > 解决方案 > jq select()返回false时如何使用回退值

问题描述

假设我有一个这样的 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": nullor "alpha": ""。但我不知道如何将它整合到我的select()通话中。

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

标签: jsonselectjqdefaultkey-value

解决方案


该问题的 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)

推荐阅读