原始问题有两个不同的子问题,一个与使用 .. 相关,但未参考已发布的 JSON 示例,另一个基于特定类型的 JSON 输入。此响应使用基于使用paths 的策略,大致如下:
reduce pv as [$p,$v] (null; setpath($p; $v))
这可能会也可能不会根据需要处理数组,这部分取决于所需的内容。如果一般不需要数组中的null 值,则添加对walk/1 的调用如下是合适的:
walk(if type == "array" then map(select(. != null)) else . end)
或者,如果必须保留原始中存在的null 值,则可以使用下面附录中详述的策略。
(1) 以使用..为特征的问题
def pv:
paths as $p
| getpath($p)
| . as $v
| (.nodes? // empty)[] | select(.focused == true)
| [$p,$v];
reduce pv as [$p,$v] (null; setpath($p; $v))
如上所述,要消除所有数组中的所有空值,您可以调用walk/1。否则,如果null 的值被setpath 插入到数组中以保留原始结构方面,请参阅下面的附录。
(2) 对于示例 JSON,以下内容就足够了:
def pv:
paths as $p
| getpath($p)
| . as $v
| (.node? // empty) | select(.foo == "bar")
| [$p,$v];
reduce pv as [$p,$v] (null; setpath($p; $v))
对于给定的样本,这会产生:
{"node":[{"node":{"foo":"bar"}}]}
对于类似的输入,如果想从数组中删除null 值,只需像以前一样添加对walk/1 的调用即可;另请参阅下面的附录。
附录
如果不需要 setpath 可能插入到数组中的 null 值以保留原始结构,最简单的方法是将原始 JSON 中的 null 值更改为某个独特的值(例如“:null: "),执行选择,修剪 null 值,然后将独特的值转换回 null。
示例
例如,考虑 foo/bar 示例的这个变体:
{
"node": [
{
"node": {
"foo": "foo0"
}
},
{
"node": {
"foo": "bar",
"trouble": [
null,
1,
null
]
}
},
{
"node": {
"foo": "foo1"
}
},
{
"node": {
"foo": "bar",
"trouble": [
1,
2,
3
]
}
}
],
"nodes": [
{
"node": {
"foo": "foo0"
}
},
{
"node": {
"foo": "bar",
"trouble": [
null,
1,
null
]
}
}
]
}
使用“:null:”作为区别值,可以使用前面针对这种情况显示的“main”程序的以下变体:
walk(if type == "array" then map(if . == null then ":null:" else . end) else . end)
| reduce pv as [$p,$v] (null; setpath($p; $v))
| walk(if type == "array"
then map(select(. != null) | if . == ":null:" then null else . end)
else . end)