JSON 合并
免费在线 JSON 合并工具,一键把多个 JSON 对象按指定策略(深度/浅层/数组拼接/数组替换)合并成一个,提供 4 种冲突解决模式,适合多源数据聚合、配置分层、i18n 合并等场景。
相关推荐
什么是 JSON 合并(JSON Merge)?
JSON 合并(JSON Merge)是把两个或多个 JSON 对象按一定规则合并成一个新对象的操作。它在工程里出现频率极高:① 把多个微服务返回的 JSON 拼成一个统一响应(BFF 层聚合);② 把 base 配置、env 配置、用户配置按"环境覆盖"逻辑合并成最终配置(Node.js config、Viper、Spring Cloud Config);③ 把多个 i18n 翻译文件合并、覆盖、补充成完整字典;④ 把多个 mock 数据数组合并成完整测试数据;⑤ 把多个 API 分页响应合并成全量结果。
合并的难点不在"合",而在"如何处理冲突"。常见冲突解决策略有 4 种:① **深度合并(Deep Merge)**:递归进入嵌套对象,对每个键分别合并,只有叶子节点冲突时才覆盖,适合配置分层;② **浅层合并(Shallow Merge)**:只合并顶层键,同名键整段覆盖,语义最简单,类似 `Object.assign`;③ **数组拼接(Array Concat)**:数组类型的值拼接成一个长数组并保留所有元素顺序,适合 API 聚合;④ **数组替换(Array Replace)**:数组类型的值以后输入的为准直接覆盖,适合配置覆盖。
实现层面,深度合并通常使用栈式递归:先检查两边都是普通对象(不是数组、不是 null),然后对每个键递归处理;遇到类型不一致(如同名键一边是对象一边是数组),一般按"后输入的为准"处理,不会做类型转换。GeekFormat 的 JSON 合并工具内置上述 4 种策略,可在页面上直接切换;可一次粘贴 2 到 N 段 JSON,自动按顺序合并,输出统一格式化结果。整个合并过程在浏览器本地完成,原始数据不上传。
适用场景
- OpenAPI 文档聚合:后端把多个微服务的 Swagger/OpenAPI JSON 用深度合并生成统一 API 网关入口。
- K8s 部署配置合并:运维把 Helm values.yaml、ConfigMap、Secret 三份 JSON 按环境栈式深度合并,输出最终部署清单。
- 单元测试 Fixture 拼接:QA 把基础数据集 JSON 与多个边界场景 JSON 用数组拼接策略合并,构造完整测试输入。
- 日志离线分析:数据分析师把 ELK 或 Kafka 多分区导出的多条 JSON 日志合并为单文件,便于统计与差异对比。
- 前端依赖清单整合:把多个子项目的 package.json 用数组拼接 + 去重合并 dependencies 字段,输出统一依赖清单。
- 多渠道客服会话归档:把微信、邮件、Web 表单多渠道聊天记录 JSON 合并为统一会话档案,便于后续检索分析。
- 数据契约链路:先经 JSON 修复清洗脏数据,再在本工具按深度策略合并,最后用 Schema 校验结果作为接口契约。
- 前后端联调:把后端多份接口响应 JSON 合并后,喂给 JSON 转 TypeScript 工具生成前端强类型定义。
- 跳过空值合并:把含 null 的覆盖 JSON 与有效配置用深度合并加跳过 null 策略合并,避免有效字段被 null 清空。
- 图表配置个性化:把 ECharts 基础配置 JSON 与用户自定义 series JSON 深度合并,渲染出符合产品需求的图表。
- Feature Flag 覆盖:产品把默认功能开关 JSON 与灰度实验配置用数组替换策略合并,让后输入的实验值覆盖基线值。
- 竞品差异对比准备:把本地 JSON 与抓取的竞品 JSON 用数组拼接合并后送入 diff 工具,快速定位字段差异。
使用方法
- 将 2 到 N 段需要合并的 JSON 依次粘贴到左侧输入框(默认 2 个),或点击「+」添加更多输入
- 在工具栏下拉框中选择合并策略:深度合并(Deep)/ 浅层合并(Shallow)/ 数组拼接(Array Concat)/ 数组替换(Array Replace)
- 点击「合并」按钮,右侧输出框会显示合并后的格式化结果;如输入有语法错误会显示具体行号和报错信息
- 确认结果无误后点击「复制」把合并结果放入剪贴板,或点击「下载」保存为 merged.json 文件继续做格式化、Schema 校验等后续处理
功能特点
- 4 种合并策略:深度合并 / 浅层合并 / 数组拼接 / 数组替换,可一键切换满足不同业务场景
- 支持 2 到 N 段 JSON:默认 2 个输入框,可点「+」动态添加更多源 JSON,灵活适配多源聚合
- 深度递归合并:智能处理多层嵌套对象,对叶子节点冲突按指定策略处理,保留所有有效字段
- 灵活冲突解决:顶层冲突时按所选策略执行;嵌套对象冲突时进入深层合并;数组冲突时按 arrayConcat/arrayReplace 区分处理
- 输出统一格式化:合并结果以 2 空格缩进显示,便于人工审阅和直接复制到下游工具
- 实时合并执行:粘贴完成点击「合并」即得结果,错误时显示具体 JSON 行号和报错信息
- 本地处理保护隐私:解析、合并、格式化全部在浏览器本地完成,输入内容不发送到任何服务器
- 无缝衔接下游:合并结果可一键复制到 JSON 格式化、Schema 校验、代码生成等工具中继续处理
代码示例
使用 lodash merge 进行 JavaScript 深度合并
javascript// npm install lodash.merge
import merge from 'lodash.merge';
const a = { user: { name: 'Alice', age: 28 }, tags: ['admin'] };
const b = { user: { email: 'a@x.com', age: 29 }, tags: ['editor'] };
// 深度合并: 嵌套对象递归合并, 叶子节点后输入覆盖前值
const deep = merge({}, a, b);
console.log(deep);
// => { user: { name: 'Alice', age: 29, email: 'a@x.com' }, tags: ['admin', 'editor'] }
// 浅层合并: 顶层键整段覆盖, 不进入嵌套
const shallow = Object.assign({}, a, b);
console.log(shallow);
// => { user: { email: 'a@x.com', age: 29 }, tags: ['editor'] }使用 mergedeep 进行 Python 深度合并
python# pip install mergedeep
from mergedeep import merge
a = {"user": {"name": "Alice", "age": 28}, "tags": ["admin"]}
b = {"user": {"email": "a@x.com", "age": 29}, "tags": ["editor"]}
# 深度合并
result = merge(a, b)
print(result)
# => {'user': {'name': 'Alice', 'age': 29, 'email': 'a@x.com'}, 'tags': ['admin', 'editor']}
# 注意: mergedeep 默认数组合并, 字符串/数字覆盖
# 如需数组覆盖, 加 strategy='override'使用 jq -s 在命令行合并多个 JSON
bash# 把多个 JSON 数组合并成一个长数组
jq -s 'add' a.json b.json c.json
# 把多个 JSON 对象递归合并 (jq 1.6+)
jq -s 'reduce .[] as $item ({}; . * $item)' a.json b.json
# 浅层合并: 把 b 顶层键覆盖到 a
jq -s '.[0] * .[1]' a.json b.json
# 数组合并后只保留去重后的 id 字段
jq -s '[.[].items[]] | unique_by(.id)' a.json b.json常见问题
JSON 合并和 JSON 拼接是一回事吗?
不完全一样。"拼接"通常指字符串直接拼在一起,没有结构;"合并"指按 JSON 结构递归把多个对象合成一个,会处理键名冲突。本工具指后者——结构化的 JSON 合并。
深度合并和浅层合并怎么选?
浅层合并:只处理顶层键,同名键整段替换,类似 `Object.assign`,最简单直接。深度合并:递归进入嵌套对象,对每个叶子节点分别合并,更智能。如果你的多个 JSON 都在不同子路径上添加字段(如 base.user.name 与 override.user.email),用深度合并;如果希望整个子对象一次性替换,用浅层合并。
数组合并时按顺序还是按索引?
本工具默认按"拼接"语义:把多个数组合并成一个长数组并保留所有元素顺序。如果你的两个数组长度相同、想按下标逐项覆盖,请切换到 "arrayReplace" 并手工把数组用对象结构包一层。
键名冲突时如何决定谁覆盖谁?
按输入顺序决定:后面的 JSON 覆盖前面的同名键(浅层/数组替换策略下整段覆盖,深度合并下仅覆盖叶子节点)。如果希望"先输入的优先",把输入顺序调换即可。
支持合并 JSON 数组吗?
支持。两种典型场景:① 多个 JSON 都是数组 → 用 "arrayConcat" 拼接成一个长数组;② 多个 JSON 都是对象、其中某字段是数组 → 用 "arrayConcat" 把多个数组合并,或用 "arrayReplace" 以后输入的为准。
可以一次合并超过 2 个 JSON 吗?
可以。默认提供 2 个输入框,点击「+」按钮可动态添加更多输入;所有输入按从上到下顺序依次合并。理论上不限制数量,但浏览器内存会限制单段大小。
合并后键的顺序是怎么确定的?
深度合并:第一个 JSON 的键顺序优先,第二个 JSON 的新键追加到对应层级的末尾。浅层合并:按输入顺序,第一个 JSON 全部键先出现,后续 JSON 的新键追加在顶层;同名键保留第一个的顺序不变。
工具会修改字段类型吗?
不会主动改类型。如果浅层/数组替换策略下两个 JSON 的同名键一个是对象、一个是数组,会按"后输入的为准"直接覆盖,不会做类型转换。深度合并仅在"两边都是普通对象"时递归,其它情况都按覆盖处理。
能保留 null 值吗?
可以。null 在 JSON 中是合法值,本工具会把 null 当作普通叶子值处理:浅层/数组替换时后输入的 null 会覆盖前值;深度合并时遇到 null 会按覆盖规则处理,不会被特殊跳过。
合并后会输出统计信息吗?
会的。结果区会显示参与合并的 JSON 段数和总键数量,便于快速核对结果;详细字段列表请直接查看右侧格式化输出。
工具会上传我的 JSON 到服务器吗?
不会。解析、合并、格式化全部在浏览器本地完成,输入与中间结果不发送到任何服务器。可离线使用,适合处理含敏感信息(如生产环境配置、内部 API 响应)的多源 JSON。
和 JSON 格式化、Schema 校验配合使用的最佳顺序是什么?
推荐链路:① JSON 修复(清洗非法 JSON)→ ② 本工具 JSON 合并(多源合并)→ ③ JSON 格式化(统一缩进)→ ④ JSON Schema 校验(验证最终结构)→ ⑤ 后续代码生成(TypeScript / Java / Go 等)。按需选择其中几步即可。
故障排查
合并提示 "Unexpected token" 或 "Invalid JSON"
原因:至少有一个输入框里的 JSON 不合法。解决方法:先把出错的 JSON 粘贴到「JSON 修复」工具清洗(自动处理尾逗号、单引号、未加引号键等),再回到本工具合并;或检查是否漏写了外层大括号 / 方括号。
合并后某些字段没出现
原因:浅层/数组替换策略下,同名键被后输入的整段覆盖;深度合并下,null 值的字段也会覆盖前面的对象。解决方法:把策略切换为「深度合并」逐层查看;如果确认是后输入的 null 覆盖,把 null 字段从后输入的 JSON 中删除或替换为占位值。
数组被覆盖了而不是拼接
原因:当前策略是「浅层合并」或「数组替换」。解决方法:在工具栏下拉框中切换到「数组拼接(Array Concat)」;或手工把两个数组合并成一个后再合并。
深度合并结果中对象变成了数组或反过来
原因:两个 JSON 在同名路径上"对象 vs 数组"类型不一致,深度合并遇到类型不一致会按"后输入的为准"。解决方法:统一两边的类型(都改为对象或都改为数组),或改用浅层/数组替换策略明确语义。
合并后键的顺序乱了
原因:第二个 JSON 的新键会按"插入位置"追加到第一个 JSON 之后,浏览器/解析器对纯整数键会自动按数字排序。解决方法:先对所有输入 JSON 用「JSON 排序」工具统一键名顺序,再合并;或在使用结果前再排一次。
大文件(10 MB+)合并卡死
原因:浏览器一次性 JSON.parse 多段大文本会占用大量内存。解决方法:把每个输入控制在 1-2 MB 以内;在本地用 Node.js(lodash.merge)或 Python(mergedeep)脚本处理超大文件;处理完再用本工具做小幅验证。
术语表
- JSON Merge
- 把两个或多个 JSON 对象按指定规则合并成一个新对象的操作,核心难点是"键名冲突时的解决策略"。
- Deep Merge / 深度合并
- 递归进入嵌套对象、对每个叶子节点分别合并的策略;两边都是普通对象时递归,否则按覆盖处理。
- Shallow Merge / 浅层合并
- 只合并顶层键、同名键整段覆盖的策略;JS 中等价于 `Object.assign({}, a, b)`。
- Array Concat / 数组拼接
- 数组合并策略之一:把多个数组合并成一个长数组并保留所有元素顺序;常用于 API 响应聚合。
- Array Replace / 数组替换
- 数组合并策略之一:同名数组以后输入的为准整段覆盖;常用于配置覆盖。
- Object.assign
- JavaScript 内置方法,把所有可枚举自有属性从一个或多个源对象浅拷贝到目标对象;浅合并的事实标准实现。
- lodash.merge
- Lodash 库提供的深度合并函数,是 Node.js 生态最常用的 deep merge 实现;数组合并而非覆盖。
- mergedeep (Python)
- Python 生态的深度合并库,pip install mergedeep;支持 strategy 参数控制数组合并/覆盖行为。
- jq -s 'add'
- jq 命令把多个 JSON 数组相加为单一数组;多个 JSON 对象合并需用 `reduce .[] as $item ({}; . * $item)`。
- BFF (Backend for Frontend)
- 在微服务架构中位于前端和后端服务之间的聚合层;常需要把多个服务的 JSON 响应合并成统一响应,是 JSON 合并的经典场景。
4 种 JSON 合并策略对比
| 策略 | 作用范围 | 数组处理 | 典型场景 |
|---|---|---|---|
| 深度合并 (Deep) | 递归所有嵌套层级 | 按所选 arrayConcat/arrayReplace | 多环境配置分层、i18n 字典合并 |
| 浅层合并 (Shallow) | 只合并顶层 | 整段覆盖 | Object.assign 风格的简单覆盖 |
| 数组拼接 (Array Concat) | 顶层 | 拼接成新数组 | 分页 API 聚合、mock 数据合并 |
| 数组替换 (Array Replace) | 顶层 | 后输入为准 | Feature Flag 配置覆盖 |
常见 JSON 合并实现对照表
| 实现/库 | 语言 | 默认行为 | 备注 |
|---|---|---|---|
| Object.assign | JavaScript | 浅合并 | ES2015 标准库;ES2017 后可用 `Object.assign({}, a, b)` |
| { ...a, ...b } | JavaScript | 浅合并 | 展开运算符,语法更简洁 |
| lodash.merge | JavaScript | 深度合并 | 数组合并不覆盖,npm install lodash.merge |
| mergedeep | Python | 深度合并 | strategy='override' 改数组合并为覆盖 |
| deepmerge (Python) | Python | 深度合并 | 另一种流行实现,pip install deepmerge |
| jq -s 'add' | Shell | 数组求和 | 对象合并需 `reduce .[] as $i ({}; . * $i)` |
Authoritative References
- JSON 压缩
- CSV 转 JSON
- JSON 转 CSV
- JSON Diff
- JSON Escape / Unescape
- JSON扁平化
- JSON 格式化
- JSON 生成器
- JSONPath 查询
- JSON 合并
- JSON 修复
- JSON Schema 校验
- JSON 排序
- JSON Stringify
- JSON 转 HTML
- JSON 转 Java
- JSON 转 Markdown
- JSON 转 SQL
- JSON 转 TOML
- JSON 转 TypeScript
- XML 转 JSON
- JSON 转 XML
- YAML 转 JSON
- JSON 转 YAML
- JSON 转 Python
- JSON 转 Go
- JSON 转 Rust
- JSON 转 Swift
- JSON 转 C#
- JSON 转 C++
- JSON 转 PHP