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,自動按順序合併,輸出統一格式化結果。整個合併過程在瀏覽器本地完成,原始資料不上傳。
適用場景
- 合併多個微服務 API 響應為統一的 JSON 結構供前端使用
- 聚合 base / dev / prod 多層設定檔,按環境覆蓋生成最終設定
- 把多個 i18n 翻譯檔案按語言合併、去重、補全成完整字典
- 把多個 mock 資料陣列或多個分頁 API 響應合併為完整資料集
- 前端元件合併預設設定 + 使用者自訂設定 + 遠端 A/B 實驗設定
- 資料遷移中合併多個源系統的 JSON 匯出檔案,統一為下游格式
使用方法
- 將 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 轉 Go
- JSON 轉 Rust
- JSON 轉 Swift
- JSON轉C#
- JSON 轉 C++
- JSON 轉 PHP
- JSON 轉 Python