如何使用Lodash或原生JS对数组类型属性执行分组操作
按数组类型子类别分组数据的实现方案
使用Lodash实现
由于每个数据项的sub_categories是数组结构,需要先将数据项与每个子类别一一关联,再进行分组:
const _ = require('lodash'); const data = [ { title: "data 1", sub_categories:[{ id: 1, name: 'gold'},{ id: 2, name: 'water' }] }, { title: "data 2", sub_categories:[{ id: 2, name: 'water'}] }, { title: "data 3", sub_categories:[{ id: 1, name: 'gold'},{ id: 3, name: 'fire' }] }, { title: "data 4", sub_categories:[] } ]; const result = _.chain(data) // 展开数据项与子类别的对应关系,过滤空子类别数组的项 .flatMap(item => { if (item.sub_categories.length === 0) return []; return item.sub_categories.map(sub => ({ subName: sub.name, title: item.title })); }) // 按子类别名称分组 .groupBy('subName') // 转换为预期的输出格式 .map((items, key) => ({ subcategory: key, list: items.map(({ title }) => ({ title })) })) .value(); console.log(result);
输出结果:
[ {"subcategory":"gold","list":[{"title":"data 1"},{"title":"data 3"}]}, {"subcategory":"water","list":[{"title":"data 1"},{"title":"data 2"}]}, {"subcategory":"fire","list":[{"title":"data 3"}]} ]
使用原生JavaScript实现
借助Array.reduce完成分组逻辑,同样先处理子类别展开的步骤:
const data = [ { title: "data 1", sub_categories:[{ id: 1, name: 'gold'},{ id: 2, name: 'water' }] }, { title: "data 2", sub_categories:[{ id: 2, name: 'water'}] }, { title: "data 3", sub_categories:[{ id: 1, name: 'gold'},{ id: 3, name: 'fire' }] }, { title: "data 4", sub_categories:[] } ]; // 先构建分组对象 const grouped = data.reduce((acc, item) => { // 跳过空子类别数组的项,如需保留可修改此处逻辑 if (item.sub_categories.length === 0) return acc; item.sub_categories.forEach(sub => { // 初始化子类别对应的数组 if (!acc[sub.name]) { acc[sub.name] = []; } // 收集当前数据项的title信息 acc[sub.name].push({ title: item.title }); }); return acc; }, {}); // 转换为预期的数组格式 const result = Object.entries(grouped).map(([key, list]) => ({ subcategory: key, list })); console.log(result);
输出结果与Lodash实现完全一致。如果需要保留空子类别数组的项,可修改reduce中的判断逻辑,添加subcategory: "未分类"的分组。
内容的提问来源于stack exchange,提问作者Chris Michael
相关产品推荐
相关产品推荐

