gpt4 book ai didi

json - jq:根据对象值条件递归删除对象的最简单方法

转载 作者:行者123 更新时间:2023-12-04 12:51:49 25 4
gpt4 key购买 nike

我想用 jq删除 JSON“对象”中的所有字典(我通常使用该术语来指代数组或字典)

a) 包含一个名为“delete_me”的键,并且
b) 键“delete_me”满足某个预定条件(空、非零、真等)

基本上,我想要实现的逻辑是:遍历输入,并在每个节点上,如果该节点不是数组或对象,则保留它并继续前进,否则,保留它但从中删除任何作为字典的子节点条件 a) 或 b) 失败。

有什么建议?

样本输入:

{
"a": { "foo": "bar" },
"b": {
"i": {
"A": {
"i": [
{
"foo": {},
"bar": {
"delete_if_this_is_null": false,
"an_array": [],
"another_array": [
{
"delete_if_this_is_null": null,
"foo": "bar"
}
],
"etc": ""
},
"foo2": "s"
},
{
"foo": {
"an_array": [
{
"delete_if_this_is_null": "ok",
"foo":"bar",
"another_object": { "a":1 }
},
{
"delete_if_this_is_null": null,
"foo2":"bar2",
"another_object": { "a":1 },
"name": null
}
],
"an_object": {
"delete_if_this_is_null":null,
"foo3":"bar3"
}
},
"zero": 0,
"b": "b"
}
]
}
}
}
}

如果“delete_me”键是 delete_if_this_is_null,应该让步并且预定条件是 delete_if_this_is_null == null :
{
"a": { "foo": "bar" },
"b": {
"i": {
"A": {
"i": [
{
"foo": {},
"bar": {
"delete_if_this_is_null": false,
"an_array": [],
"another_array": [],
"etc": ""
},
"foo2": "s"
},
{
"foo": {
"an_array": [
{
"delete_if_this_is_null": "ok",
"foo":"bar",
"another_object": { "a":1 }
}
]
},
"zero": 0,
"b": "b"
}
]
}
}
}
}

更新:这是解决方案:假设输入在文件“input.json”中:
jq 'def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;

def mapper(f):
if type == "array" then map(f)
elif type == "object" then
. as $in
| reduce keys[] as $key
({};
[$in[$key] | f ] as $value
| if $value | length == 0 then .
else . + {($key): $value[0]} end)
else .
end;

walk( mapper(select((type == "object" and .delete_if_this_is_null == null) | not)) )' < input.json

最佳答案

杰夫的解决方案可能会影响太多。例如,使用:

def data: [1,2, {"hello": {"delete_me": true, "a":3 }, "there": 4} ]; ];

杰夫的解决方案是空的(即什么都没有)。

因此,以下内容可能更接近您要查找的内容:
walk(if (type == "object" and .delete_me) then del(.) else . end )

对于 data ,这产生:
[1,2,{"hello":null,"there":4}]

替代方案

如果解决方案可以消除 "hello":null在上面的例子中是必需的,那么需要 jq 的 map_values/1 的一个变体。这是一种方法:
def mapper(f):
if type == "array" then map(f)
elif type == "object" then
. as $in
| reduce keys[] as $key
({};
[$in[$key] | f ] as $value
| if $value | length == 0 then .
else . + {($key): $value[0]} end)
else .
end;

data | walk( mapper(select((type == "object" and .delete_me) | not)) )

结果是:
[1,2,{"there":4}]

关于json - jq:根据对象值条件递归删除对象的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34098002/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com