我想将两个JSON对象合并为一个新对象。我尝试将jsonmerge与完整的json模式结合使用,但我不知道如何正确设置合并策略。我很确定可以做到。
码:
import json
from jsonmerge import Merger
from jsonschema import validate
full_build = {
"captures": [
{
"compiler": "gnu",
"executable": "gcc",
"cmd": ["gcc", "options", "file1.cpp"],
"cwd": ".",
"env": ["A=1", "B=2"],
},
{
"compiler": "gnu",
"executable": "gcc",
"cmd": ["gcc", "options", "file2.cpp"],
"cwd": ".",
"env": ["A=1", "B=2"],
}
]
}
incremental_build = {
"captures": [
{
"compiler": "gnu",
"executable": "gcc",
"cmd": ["gcc", "new options", "file2.cpp"],
"cwd": ".",
"env": ["A=1", "NEW=2"],
},
{
"compiler": "gnu",
"executable": "gcc",
"cmd": ["gcc", "options", "file3.cpp"],
"cwd": ".",
"env": ["A=1", "B=2"],
}
]
}
schema = {
"type" : "object",
"properties" : {
"captures": {
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"cmd" : {
"type" : "array",
"items" : {"type" : "string"},
},
"compiler" : {"type" : "string"},
"cwd" : {"type" : "string"},
"env" : {
"type" : "array",
"items" : {"type" : "string"},
},
"executable" : {"type" : "string"},
}
}
}
}
}
validate(instance=full_build, schema=schema)
mergeSchema = schema
merger = Merger(mergeSchema)
result = merger.merge(full_build, incremental_build)
print(json.dumps(result, indent=3))
结果:
{
"captures": [
{
"compiler": "gnu",
"executable": "gcc",
"cmd": [
"gcc",
"options",
"file3.cpp"
],
"cwd": ".",
"env": [
"A=1",
"B=2"
]
}
]
}
预期结果:
{
"captures": [
{
"compiler": "gnu",
"executable": "gcc",
"cmd": [
"gcc",
"options",
"file1.cpp"
],
"cwd": ".",
"env": [
"A=1",
"B=2"
]
},
{
"compiler": "gnu",
"executable": "gcc",
"cmd": [
"gcc",
"new options",
"file2.cpp"
],
"cwd": ".",
"env": [
"A=1",
"NEW=2"
]
},
{
"compiler": "gnu",
"executable": "gcc",
"cmd": [
"gcc",
"options",
"file3.cpp"
],
"cwd": ".",
"env": [
"A=1",
"B=2"
]
}
]
}
还有更多需要考虑的事情(例如比以前有更多或更少的选项/环境变量),但我认为只要一点提示,我就能设法完成任务。我真的不想硬编码它。
不,我不能更改json :(。的结构。
背景:我想合并SonarQube构建包装器输出,因为我不想做完整的构建以将所有文件都放入包装器输出。
似乎您根本不需要任何复杂的合并操作。您基本上想将两个结构的“捕获”列表组合成一个包含所有结构的新结构。可以通过制作副本并随后简单地扩展列表来实现:
full_build = ...
incremental_build = ...
combined = copy.deepcopy(full_build)
combined['captures'].extend(incremental_build['captures'])
如果要基于某些属性(例如文件名)进行“重复数据删除”,则可以使用以下方法:
def get_filename_from_capture(cmd):
return cmd["cmd"][-1]
all_captures = full_build["captures"] + incremental_build["captures"]
captures_by_filename = {
get_filename_from_capture(capture): capture for capture in all_captures
}
combined = copy.deepcopy(full_build)
combined["captures"] = list(captures_by_filename.values())
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句