JavaScript如何将含动态范围属性的对象转换为指定嵌套结构
JavaScript动态属性对象通用转换方案
场景说明
- 原始对象包含2个固定属性:
Type(类型值)、Name(名称值) - 其余为动态生成的范围属性,命名规则为
StartRangeN、EndRangeN,N为从0开始的整数,总数量不固定 - 目标结构以
Type值为外层键,内部保留Name字段,同索引的起止范围值需按顺序组装为二维数组存入List字段
实现代码
基础版(适配索引连续从0开始的场景,性能最优)
适用于范围属性严格按StartRange0/EndRange0、StartRange1/EndRange1连续生成的绝大多数场景:
const oldObj = { Type: "Fire", Name: "Shark", StartRange0: "10", EndRange0: "20", StartRange1: "30", EndRange1: "40", StartRange2: "60", EndRange2: "70" } const newObj = {} const rangeList = [] let index = 0 // 从索引0开始循环匹配,直到找不到对应属性为止 while (oldObj.hasOwnProperty(`StartRange${index}`) && oldObj.hasOwnProperty(`EndRange${index}`)) { rangeList.push([oldObj[`StartRange${index}`], oldObj[`EndRange${index}`]]) index++ } newObj[oldObj.Type] = { Name: oldObj.Name, List: rangeList }
兼容版(适配索引不连续场景)
如果存在索引断层、属性生成顺序混乱的情况,可以通过正则提取键名中的索引,排序后再组装:
function convertDynamicObj(sourceObj) { const rangeCollection = new Map() const startRangePattern = /^StartRange(\d+)$/ const endRangePattern = /^EndRange(\d+)$/ for (const key of Object.keys(sourceObj)) { const startMatch = key.match(startRangePattern) if (startMatch) { const idx = Number(startMatch[1]) if (!rangeCollection.has(idx)) rangeCollection.set(idx, []) rangeCollection.get(idx)[0] = sourceObj[key] continue } const endMatch = key.match(endRangePattern) if (endMatch) { const idx = Number(endMatch[1]) if (!rangeCollection.has(idx)) rangeCollection.set(idx, []) rangeCollection.get(idx)[1] = sourceObj[key] } } // 按索引升序排列,过滤缺少起止值的无效项 const sortedList = [...rangeCollection.entries()] .sort((prev, next) => prev[0] - next[0]) .filter(([, value]) => value.length === 2) .map(([, value]) => value) return { [sourceObj.Type]: { Name: sourceObj.Name, List: sortedList } } } // 调用示例 const newObj = convertDynamicObj(oldObj)
方案优势
- 无需提前知道动态范围属性的总数量,自动适配任意N值的场景
- 基础版无正则匹配开销,执行效率极高,适合绝大多数常规生成逻辑的场景
- 兼容版容错性强,即使索引不连续、属性顺序错乱也能正确生成目标结构
内容的提问来源于stack exchange,提问作者Sai Krishnadas
相关产品推荐
相关产品推荐

