基于JavaScript对象属性实现层级分组的方案问询
基于指定键顺序实现JavaScript对象层级分组为树形结构
核心实现思路
通过迭代层级键+节点复用的方式构建树形结构:
- 初始化根节点数组作为树形结构的起点
- 遍历每条数据,按指定键的顺序逐层向下匹配已存在的节点
- 若当前层级没有对应属性值的节点,则创建新节点并加入父节点的子列表
- 处理到最后一层键时,将当前数据挂载为叶子节点(或按需调整节点结构)
完整实现代码
function groupByHierarchy(data, keys) { const root = []; // 遍历每条原始数据 data.forEach(item => { let currentLevel = root; // 按指定键顺序逐层处理 for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = item[key]; // 查找当前层级是否已有该属性值的节点 let existingNode = currentLevel.find(node => node.name === value); if (!existingNode) { // 创建新节点,最后一层挂载原始数据,否则初始化子节点数组 existingNode = { name: value, ...(i === keys.length - 1 ? { data: item } : { children: [] }) }; currentLevel.push(existingNode); } // 进入下一层级,处理后续键 currentLevel = existingNode.children || []; } }); return root; }
示例验证
假设输入数据如下:
const inputData = [ { A: '分类1', B: '子类1-1', C: '项1-1-1', D: '值1', num: 10 }, { A: '分类1', B: '子类1-1', C: '项1-1-2', D: '值2', num: 20 }, { A: '分类1', B: '子类1-2', C: '项1-2-1', D: '值3', num: 15 }, { A: '分类2', B: '子类2-1', C: '项2-1-1', D: '值4', num: 30 } ]; const keys = ['A', 'B', 'C', 'D'];
调用函数后输出的树形结构:
[ { "name": "分类1", "children": [ { "name": "子类1-1", "children": [ { "name": "项1-1-1", "children": [ { "name": "值1", "data": { A: '分类1', B: '子类1-1', C: '项1-1-1', D: '值1', num: 10 } } ] }, { "name": "项1-1-2", "children": [ { "name": "值2", "data": { A: '分类1', B: '子类1-1', C: '项1-1-2', D: '值2', num: 20 } } ] } ] }, { "name": "子类1-2", "children": [ { "name": "项1-2-1", "children": [ { "name": "值3", "data": { A: '分类1', B: '子类1-2', C: '项1-2-1', D: '值3', num: 15 } } ] } ] } ] }, { "name": "分类2", "children": [ { "name": "子类2-1", "children": [ { "name": "项2-1-1", "children": [ { "name": "值4", "data": { A: '分类2', B: '子类2-1', C: '项2-1-1', D: '值4', num: 30 } } ] } ] } ] } ]
自定义调整说明
如果图表需要特定的节点字段(比如把data换成value,或者合并统计值),可以修改节点创建逻辑:
// 示例:最后一层节点合并num字段总和 existingNode = { name: value, ...(i === keys.length - 1 ? { value: item.num } : { children: [], value: 0 }) }; // 若节点已存在,累加数值 if (existingNode && i === keys.length - 1) { existingNode.value += item.num; }
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

