JavaScript对象键名格式转换:寻求更优雅的实现方案
优化JavaScript对象键名转换的实现方案
需求概述
需要将多层对象中所有以.0结尾的键名去掉末尾的.0,非目标格式的键名保持不变。
原对象结构
const object = { 2021: { "13.0": { data: {} }, "13.1": { data: {} }, "17.0": { data: {} }, "17.1": { data: {} }, }, 2022: { "13.0": { data: {} }, "13.1": { data: {} }, "17.0": { data: {} }, "17.1": { data: {} }, }, };
目标对象结构
const obj1 = { 2021: { "13": { data: {} }, "13.1": { data: {} }, "17": { data: {} }, "17.1": { data: {} }, }, 2022: { "13": { data: {} }, "13.1": { data: {} }, "17": { data: {} }, "17.1": { data: {} }, }, };
现有实现
你提供的代码可以正常运行,但存在重复判断和引用修改原对象的问题,代码如下:
const obj1 = {}; for (let year in object) { obj1[year] = object[year]; for (let number in object[year]) { const keyOk = number.endsWith('.0') ? number.slice(0, number.length - 2) : number; obj1[year][keyOk] = object[year][number]; if (number.endsWith('.0')) { delete object[year][number]; } } }
更优实现方案
方案一:纯函数式处理(不修改原对象)
采用函数式编程风格,通过Object.entries和Object.fromEntries转换键值对,完全不修改原对象,代码简洁易读:
const transformObject = (obj) => { return Object.fromEntries( Object.entries(obj).map(([year, versions]) => { const transformedVersions = Object.fromEntries( Object.entries(versions).map(([version, data]) => { // 统一处理键名,避免重复判断 const newKey = version.endsWith('.0') ? version.slice(0, -2) : version; return [newKey, data]; }) ); return [year, transformedVersions]; }) ); }; const obj1 = transformObject(object);
优势:纯函数无副作用,不会意外修改原对象,代码结构清晰,符合现代JS编程习惯。
方案二:递归通用处理(支持深层嵌套)
如果未来对象结构可能有更深层级,递归方案可以一次性处理所有层级的目标键名,扩展性更强:
const transformKeys = (obj) => { // 非对象类型直接返回 if (typeof obj !== 'object' || obj === null) return obj; return Object.fromEntries( Object.entries(obj).map(([key, value]) => { const newKey = key.endsWith('.0') ? key.slice(0, -2) : key; // 递归处理子对象 return [newKey, transformKeys(value)]; }) ); }; const obj1 = transformKeys(object);
优势:兼容任意深度的对象结构,无需修改代码即可适配未来需求变化。
方案三:简洁修改原对象(允许修改原对象时使用)
如果业务场景允许直接修改原对象,可以简化代码逻辑,减少重复判断:
// 遍历年份层级 for (const year of Object.keys(object)) { const versions = object[year]; // 遍历版本号层级 for (const version of Object.keys(versions)) { if (version.endsWith('.0')) { const newKey = version.slice(0, -2); versions[newKey] = versions[version]; delete versions[version]; } } } // 如果需要新对象,可浅拷贝原对象 const obj1 = {...object};
优势:代码更精简,内存占用更低,适合对性能有要求且允许修改原对象的场景。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

