合并两个复杂的JSON对象

鼠疫

我想将两个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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章