You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript(ES5)嵌套分组优化:如何仅调用一次groupBy函数

实现一次_.groupBy完成嵌套分组的方案

我明白你想要的效果——只用一次Underscore的_.groupBy就能完成先按模块(moduleID/moduleTitle)、再按分类(categoryID/categoryTitle)的嵌套分组,而不是先分模块再遍历每个模块分分类对吧?没问题,咱们可以通过复合分组键+结果重组的方式实现,下面直接上代码和思路:

1. 先模拟你的数据源

假设你的原始数据是这样的对象数组:

const items = [
  { moduleID: 1, moduleTitle: '前端基础', categoryID: 101, categoryTitle: 'HTML', content: 'HTML入门' },
  { moduleID: 1, moduleTitle: '前端基础', categoryID: 102, categoryTitle: 'CSS', content: 'CSS布局' },
  { moduleID: 2, moduleTitle: '前端框架', categoryID: 101, categoryTitle: 'Vue', content: 'Vue组件化' },
  { moduleID: 2, moduleTitle: '前端框架', categoryID: 103, categoryTitle: 'React', content: 'React Hooks' },
];

2. 一次_.groupBy+结果重组的代码

const _ = require('underscore');

// 第一步:用「模块ID-分类ID」的复合字符串作为分组键,只调用一次groupBy
const groupedByCompositeKey = _.groupBy(items, item => `${item.moduleID}-${item.categoryID}`);

// 第二步:将复合键的分组结果转换为你需要的嵌套结构
const nestedGroups = _.reduce(groupedByCompositeKey, (result, groupItems, compositeKey) => {
  // 拆分复合键,得到模块ID和分类ID
  const [moduleID, categoryID] = compositeKey.split('-').map(Number);
  // 取组内第一个元素的标题(业务上同moduleID的moduleTitle、同categoryID的categoryTitle应该一致)
  const { moduleTitle, categoryTitle } = groupItems[0];

  // 检查当前结果中是否已有该模块的分组
  let moduleGroup = _.find(result, mod => mod.moduleID === moduleID);
  if (!moduleGroup) {
    // 如果没有,创建新的模块分组并加入结果数组
    moduleGroup = {
      moduleID,
      moduleTitle,
      categories: []
    };
    result.push(moduleGroup);
  }

  // 将当前分类的分组加入对应模块的categories数组
  moduleGroup.categories.push({
    categoryID,
    categoryTitle,
    items: groupItems
  });

  return result;
}, []);

3. 思路解释

  • 复合分组键:把moduleID和categoryID拼接成唯一字符串(比如1-101),这样一次_.groupBy就能把所有属于同一模块+同一分类的项归到一组。
  • 结果重组:用_.reduce遍历这些复合键分组,把它们重新组织成「模块包含分类」的嵌套结构——先判断模块是否已存在,不存在则创建;然后把当前分类的分组加入对应模块的分类列表。

这样就完全避免了两次遍历分组的操作,只调用了一次_.groupBy,最终得到的nestedGroups结构就是你需要的嵌套分组结果。

内容的提问来源于stack exchange,提问作者Renaud is Not Bill Gates

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:43:45