如何将JSON中点分隔外部子属性合并到子对象且外部值优先
问题描述
给定如下JSON对象:
{ "client":null, "user":{ "email":"frank55@gmail.com", "firstName":"Frank", "lastName":"Palto", "fullName":"Frank Palto", "tags":[ "Ops", "Dev" ], "hasRegistered": true, "url":"" }, "user.email":"joseph55@gmail.com", "user.firstName":"Joseph", "user.lastName":"Enoc", "user.mobileNumber":"0123451111" }
需要将其中的user对象与外部的点分隔属性(如user.email)合并,生成统一的user对象,合并规则为:外部点分隔属性归入对应嵌套对象,且其值优先覆盖原有值。期望输出如下:
{ "client":null, "user":{ "email":"joseph55@gmail.com", "firstName":"Joseph", "lastName":"Enoc", "fullName":"Frank Palto", "mobileNumber":"0123451111", "tags":[ "Ops", "Dev" ], "hasRegistered": true, "url":"" } }
要求无需预定义模型,自动检测所有点分隔属性并执行合并。
实现方案
核心思路是遍历原JSON对象的所有键,识别点分隔的嵌套路径,将对应值写入到嵌套对象中(路径不存在则创建),最后移除原对象中的点分隔键。以下是JavaScript的实现示例,其他语言可参考相同逻辑:
步骤说明
- 遍历原对象的每个键值对
- 对每个键,判断是否包含
.:- 若包含,拆分键为路径数组(如
user.email拆分为['user', 'email']) - 从根对象开始,逐层访问嵌套对象,若某层不存在则创建空对象
- 将值赋值到路径的最终节点,覆盖原有值
- 若包含,拆分键为路径数组(如
- 处理完所有点分隔键后,删除原对象中的这些键
完整代码示例
function mergeDotSeparatedKeys(obj) { // 复制原对象避免修改原数据(可选,按需调整) const result = {...obj}; // 收集需要删除的点分隔键 const keysToDelete = []; for (const key of Object.keys(result)) { if (key.includes('.')) { keysToDelete.push(key); const path = key.split('.'); let current = result; // 遍历路径(除最后一个节点),创建不存在的嵌套对象 for (let i = 0; i < path.length - 1; i++) { const segment = path[i]; if (!current[segment] || typeof current[segment] !== 'object' || current[segment] === null) { current[segment] = {}; } current = current[segment]; } // 赋值并覆盖原有值 const finalKey = path[path.length - 1]; current[finalKey] = result[key]; } } // 删除原对象中的点分隔键 keysToDelete.forEach(key => delete result[key]); return result; } // 测试示例 const input = { "client":null, "user":{ "email":"frank55@gmail.com", "firstName":"Frank", "lastName":"Palto", "fullName":"Frank Palto", "tags":["Ops","Dev"], "hasRegistered": true, "url":"" }, "user.email":"joseph55@gmail.com", "user.firstName":"Joseph", "user.lastName":"Enoc", "user.mobileNumber":"0123451111" }; const output = mergeDotSeparatedKeys(input); console.log(JSON.stringify(output, null, 2));
关键细节
- 空值处理:原对象中如
client这类null值不会被误修改,仅处理点分隔键触发的嵌套路径 - 数组保留:原嵌套对象中的数组(如
tags)会完整保留,除非有对应点分隔键覆盖 - 动态适配:无需预定义模型结构,自动支持任意层级的点分隔路径(如
user.address.city) - 覆盖优先级:点分隔键的值直接覆盖嵌套对象原有值,完全符合需求
内容的提问来源于stack exchange,提问作者tendai
相关产品推荐
相关产品推荐

