如何将稀疏JavaScript对象转换为嵌套对象?
如何将扁平的JavaScript对象转换为嵌套数组结构
没问题,我来帮你搞定这个对象结构转换~这里有两种实用的实现方法,先看一个清晰易懂的版本,再给你一个更简洁的写法:
方法一:遍历处理(直观易懂)
这种方法逻辑清晰,适合新手理解,一步步拆解字段并重组结构:
let values = { 'ban_Name': "test", 'bank': "yes", 'cont_1-counterName': "Cname1", 'cont_1-obl': "obl1", 'cont_1-orig': "orig 1", 'cont_2-counterName': "Cname2", 'cont_2-obl': "obl2", 'cont_2-orig': "orig 2", 'cont': "yes", 'creditors': "no", }; // 初始化结果对象,同时准备空的conts数组 const result = {}; const conts = []; // 遍历原对象的所有键值对 for (const [key, value] of Object.entries(values)) { // 判断是否是cont_N-xxx格式的字段 if (key.startsWith('cont_') && key.includes('-')) { // 拆分出前缀(cont_1)和字段名(counterName) const [prefix, fieldName] = key.split('-'); // 提取数字部分,转成数组的0基索引(cont_1对应数组第0位) const index = parseInt(prefix.split('_')[1], 10) - 1; // 如果数组对应位置还没有对象,先创建一个空对象 if (!conts[index]) { conts[index] = {}; } // 将字段值赋值到对应对象中 conts[index][fieldName] = value; } else { // 非目标字段直接复制到结果对象 result[key] = value; } } // 把整理好的conts数组添加到结果对象 result.conts = conts; console.log(result);
逻辑拆解:
- 用
Object.entries()遍历原对象,同时获取键和值; - 通过
startsWith和includes筛选出需要重组的字段; - 拆分字段名得到索引和属性名,将值对应到数组的指定位置;
- 其他字段直接保留到结果对象中。
方法二:使用reduce简化代码
如果喜欢更简洁的写法,可以用Array.reduce()来完成累计转换,代码更紧凑:
let values = { 'ban_Name': "test", 'bank': "yes", 'cont_1-counterName': "Cname1", 'cont_1-obl': "obl1", 'cont_1-orig': "orig 1", 'cont_2-counterName': "Cname2", 'cont_2-obl': "obl2", 'cont_2-orig': "orig 2", 'cont': "yes", 'creditors': "no", }; const result = Object.entries(values).reduce((acc, [key, value]) => { // 用正则匹配cont_N-xxx格式的字段 const match = key.match(/^cont_(\d+)-(\w+)/); if (match) { const [_, num, field] = match; const index = parseInt(num, 10) - 1; // 用扩展运算符合并已有对象和新字段 acc.conts[index] = { ...(acc.conts[index] || {}), [field]: value }; } else { // 非目标字段直接存入累计对象 acc[key] = value; } return acc; }, { conts: [] }); // 初始值是包含空conts数组的对象 console.log(result);
逻辑拆解:
- 用
reduce从空对象开始累计结果,初始值包含conts空数组; - 正则表达式
/^cont_(\d+)-(\w+)/直接提取数字和字段名,比拆分字符串更精准; - 用
扩展运算符合并已有属性和新属性,避免重复创建对象。
注意事项
- 如果原对象中
cont_N的数字不连续(比如存在cont_1和cont_3),数组中会出现undefined项,可通过result.conts = conts.filter(item => item)过滤掉空值; - 如果字段名包含特殊字符,需要调整正则表达式或拆分逻辑,确保能正确提取属性名;
- 两种方法都能完美适配你给出的输入格式,输出结果和你期望的完全一致。
内容的提问来源于stack exchange,提问作者Samz
相关产品推荐
相关产品推荐

