如何将CSV读取的二维数组转换为可变深度的嵌套对象数组?
多维数组转层级嵌套结构的解决方案
需求说明
将从CSV读取的二维数组(子数组元素个数可大于3),转换为每层包含text字段和sub_list子列表的嵌套结构,示例如下:
输入数组:
const data = [ ['P1','A1','W1'],['P1','A1','W2'],['P1','A1','W3'], ['P1','A2','W4'],['P1','A2','W5'],['P1','A2','W6'], ['P2','A3','W7'],['P2','A3','W8'],['P2','A3','W9'] ];
输出结构:
[ { "text": "P1", "sub_list": [ { "text": "A1", "sub_list": [ {"text": "W1", "sub_list": []}, {"text": "W2", "sub_list": []}, {"text": "W3", "sub_list": []} ] }, { "text": "A2", "sub_list": [ {"text": "W4", "sub_list": []}, {"text": "W5", "sub_list": []}, {"text": "W6", "sub_list": []} ] } ] }, { "text": "P2", "sub_list": [ { "text": "A3", "sub_list": [ {"text": "W7", "sub_list": []}, {"text": "W8", "sub_list": []}, {"text": "W9", "sub_list": []} ] } ] } ]
可行解决方案
1. 递归实现方案
核心思路是按当前层级的元素分组,对每组的剩余元素递归生成子列表:
function convertToNested(data) { if (!data.length) return []; // 按当前层级的第一个元素分组 const groups = {}; data.forEach(item => { const key = item[0]; groups[key] = groups[key] || []; if (item.length > 1) { groups[key].push(item.slice(1)); } }); // 转换为目标结构并递归处理子层级 return Object.entries(groups).map(([text, children]) => ({ text, sub_list: convertToNested(children) })); } // 测试调用 const result = convertToNested(data); console.log(JSON.stringify(result, null, 2));
- 优势:代码简洁,逻辑直观,容易理解
- 注意:若数据层级极深,可能触发JavaScript的递归深度限制
2. 迭代实现方案
通过逐层遍历构建嵌套结构,避免递归深度问题:
function convertToNestedIterative(data) { const root = []; data.forEach(item => { let currentLevel = root; item.forEach((text, index) => { // 查找当前层级是否已存在该节点 let targetNode = currentLevel.find(node => node.text === text); if (!targetNode) { targetNode = { text, sub_list: [] }; currentLevel.push(targetNode); } // 进入下一层级(最后一个元素无需继续) if (index !== item.length - 1) { currentLevel = targetNode.sub_list; } }); }); return root; } // 测试调用 const result = convertToNestedIterative(data); console.log(JSON.stringify(result, null, 2));
- 优势:无递归深度限制,性能更稳定,适合层级极深的数据集
- 注意:逻辑相对递归稍复杂,但可读性依然良好
内容的提问来源于stack exchange,提问作者Mohammad Ubaid
相关产品推荐
相关产品推荐

