我正在尝试替换复杂JSON对象中的对象。似乎工具jq
可以提供完美的解决方案,但我真的在努力选择正确的过滤器/链条。
我有一个完整的配置JSON对象,看起来像这样(有更多的键,缩短了它的插图):
{
"some-array": [
{
"name": "foo",
"attr": "value"
},
{
"name": "foo bar",
"attr": "value"
},
{
"name": "foo bar baz",
"attr": "value"
}
],
"some-other-array": []
}
现在我有另一个包含带有更新对象的数组的对象,我需要以某种方式与完整配置合并。我需要按名称查找嵌套对象,如果它还不存在则添加它,如果它存在则替换它。
{
"some-array": [
{
"name": "foo",
"attr": "new-value",
"new-attrib": "new-value"
},
{
"name": "foo bar",
"attr": "new-value"
}
]
}
因此,通过上面的例子,我的预期结果将是:
{
"some-array": [
{
"name": "foo",
"attr": "new-value",
"new-attrib": "new-value"
},
{
"name": "foo bar",
"attr": "new-value"
},
{
"name": "foo bar baz",
"attr": "value"
}
],
"some-other-array": []
}
我已经尝试select(."some-array"[].name == "foo")
作为jq
过滤器开始使用其他一些东西,但我很难在这里继续前进,并且非常感谢一些灵感/实际的解决方案。
任何人都可以告诉我,我想要实现的目标是jq
实际可行,还是我必须找到另一种解决方案?
答案 0 :(得分:1)
是的,这是可能的,事实上,在最初陈述的问题的各种解释下很容易。
以下解决了最初陈述的问题,“它”被解释为.["some-array"]
而不是其成分。
假设$update
持有包含所显示更新信息的对象,则可以使用此过滤器执行更新:
.["some-array"] = ($update | .["some-array"])
有许多方法可以赋予$update
所需的值。
答案 1 :(得分:1)
以下是更新问题的解决方案。此解决方案假定名称是字符串值。它依赖于两个辅助函数:
# array-to-hash
def a2h(f): reduce .[] as $x ({}; . + {($x | f): $x});
# hash-to-array
def h2a: . as $in | reduce keys_unsorted[] as $k ([]; . + [$in[$k]]);
第一个创建了#34;哈希"基于输入数组,第二个实现逆操作。
使用这些辅助函数,可以编写解决方案:
.["some-array"] |= (a2h(.name) + ($update|.["some-array"] | a2h(.name)) | h2a)
其中$update
是"新"值。这个解决方案依赖于"右支配"对象添加。
对于给定的示例,输出为:
{
"some-array": [
{
"name": "foo",
"attr": "new-value",
"new-attrib": "new-value"
},
{
"name": "foo bar",
"attr": "new-value"
},
{
"name": "foo bar baz",
"attr": "value"
}
],
"some-other-array": []
}