如何按多层嵌套值分组任务对象数组?
多级分类任务数组的结构化处理方案
问题背景
我有一个包含任务的对象数组,每个任务归属于一级分类(primary_category)和二级分类(secondary_category):
let tasks = [ { id: 1, name: 'Cleanup desk', primary_category: { id: 1, name: 'Indoor' }, secondary_category: { id: 2, name: 'Surfaces' } }, { id: 2, name: 'Cleanup office floors', primary_category: { id: 1, name: 'Indoor' }, secondary_category: { id: 3, name: 'Ground' } }, { id: 3, name: 'Water plants', primary_category: { id: 2, name: 'Outdoor' }, secondary_category: { id: 3, name: 'Irrigation' } } ];
需要将数组转换为一级分类 -> 二级分类 -> 任务的层级结构,用于前端折叠面板组件,期望得到的最终结构如下:
let tasks_categorized = [ { id: 1, name: 'Indoor', secondary_categories: [ { id: 2, name: 'Surfaces', tasks: [ { id: 1, name: 'Cleanup desk' } ] }, { id: 3, name: 'Ground', tasks: [ { id: 2, name: 'Cleanup office floors' } ] } ] }, { id: 2, name: 'Outdoor', secondary_categories: [ { id: 3, name: 'Irrigation', tasks: [ { id: 3, name: 'Water plants' } ] } ] } ];
尝试使用lodash的groupBy方法,但该方法无法直接实现这种多级嵌套的分组逻辑,求可行的解决办法。
解决方案
方案一:原生JavaScript实现
通过遍历任务数组,利用Map快速查找已存在的分类,逐步构建层级结构,无需依赖第三方库:
function categorizeTasks(tasks) { const result = []; const primaryCategoryMap = new Map(); tasks.forEach(task => { const { primary_category, secondary_category, id, name } = task; // 初始化一级分类(不存在则创建) if (!primaryCategoryMap.has(primary_category.id)) { const primaryItem = { id: primary_category.id, name: primary_category.name, secondary_categories: [] }; primaryCategoryMap.set(primary_category.id, primaryItem); result.push(primaryItem); } const currentPrimary = primaryCategoryMap.get(primary_category.id); // 初始化二级分类(不存在则创建) let currentSecondary = currentPrimary.secondary_categories.find(sc => sc.id === secondary_category.id); if (!currentSecondary) { currentSecondary = { id: secondary_category.id, name: secondary_category.name, tasks: [] }; currentPrimary.secondary_categories.push(currentSecondary); } // 将当前任务添加到对应二级分类下 currentSecondary.tasks.push({ id, name }); }); return result; } // 调用示例 const categorizedTasks = categorizeTasks(tasks); console.log(categorizedTasks);
方案二:结合lodash实现多级分组
如果项目中已经使用lodash,可以先通过groupBy完成基础分组,再逐层转换为目标结构:
// 确保已引入lodash const _ = require('lodash'); function categorizeTasksWithLodash(tasks) { // 第一步:按一级分类ID分组 const groupedByPrimary = _.groupBy(tasks, task => task.primary_category.id); // 转换为一级分类数组 return Object.values(groupedByPrimary).map(primaryGroup => { // 提取一级分类的基础信息 const primaryInfo = primaryGroup[0].primary_category; // 第二步:对当前一级分类下的任务按二级分类ID分组 const groupedBySecondary = _.groupBy(primaryGroup, task => task.secondary_category.id); // 转换为二级分类数组 const secondaryCategories = Object.values(groupedBySecondary).map(secondaryGroup => { const secondaryInfo = secondaryGroup[0].secondary_category; // 提取任务的id和name字段 const taskList = secondaryGroup.map(({ id, name }) => ({ id, name })); return { ...secondaryInfo, tasks: taskList }; }); return { ...primaryInfo, secondary_categories: secondaryCategories }; }); } // 调用示例 const categorizedTasks = categorizeTasksWithLodash(tasks); console.log(categorizedTasks);
内容的提问来源于stack exchange,提问作者Kheber
相关产品推荐
相关产品推荐

