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

如何在JavaScript中实现对象数组多键分组求和的通用函数?

基于Lodash实现对象数组的分组求和通用函数

实现思路

完全可以通过Lodash的_.groupBy和_.sumBy结合递归逻辑实现需求,同时支持单层和多层分组场景。核心思路是逐层处理分组字段,每完成一层分组后,对剩余分组字段递归处理,直到无剩余分组字段时计算求和字段的总和。

示例数据

const data = [
  {
    continent:'North America',
    country:'us',
    state:'ma',
    population: 1567986,
    fee: 24343
  },
  {
    continent:'North America',
    country:'us',
    state:'tx',
    population: 7567986,
    fee: 119343
  },
  {
    continent:'North America',
    country:'ca',
    state:'on',
    population: 467986,
    fee: 3343
  },
  {
    continent:'North America',
    country:'ca',
    state:'qb',
    population: 1268986,
    fee: 54248
  },
  {
    continent:'Europe',
    country:'ge',
    state:'mc',
    population: 4268986,
    fee: 97333
  },
  {
    continent:'Europe',
    country:'it',
    state:'fl',
    population: 978353,
    fee: 248
  },
];

通用函数实现(Lodash版本)

const GroupByFunction = (array, groupbyFields, sumFields) => {
  // 递归处理分组与求和
  const groupAndSum = (items, fields) => {
    // 无剩余分组字段时,计算求和字段总和
    if (fields.length === 0) {
      return sumFields.reduce((acc, field) => {
        acc[field] = _.sumBy(items, field);
        return acc;
      }, {});
    }

    const currentField = fields[0];
    // 按当前字段分组
    const grouped = _.groupBy(items, currentField);
    
    // 对每个分组递归处理剩余字段
    return _.mapValues(grouped, (groupItems) => 
      groupAndSum(groupItems, fields.slice(1))
    );
  };

  return groupAndSum(array, groupbyFields);
};

调用示例

1. 单层分组(按continent)

const singleGroupResult = GroupByFunction(data, ['continent'], ['population', 'fee']);

输出结果:

{
  'North America': { population: 10871944, fee: 201277 },
  'Europe': { population: 5247339, fee: 97581 }
}

2. 多层分组(按continent + country)

const multiGroupResult = GroupByFunction(data, ['continent', 'country'], ['population', 'fee']);

输出结果:

{
  'North America': {
    us: { population: 9135972, fee: 143686 },
    ca: { population: 1736972, fee: 57591 }
  },
  'Europe': {
    ge: { population: 4268986, fee: 97333 },
    it: { population: 978353, fee: 248 }
  }
}

非Lodash原生实现方案

如果不想依赖第三方库,可使用原生JavaScript的Array.reduce实现:

const GroupByFunctionNative = (array, groupbyFields, sumFields) => {
  const groupAndSum = (items, fields) => {
    if (fields.length === 0) {
      return sumFields.reduce((acc, field) => {
        acc[field] = items.reduce((sum, item) => sum + item[field], 0);
        return acc;
      }, {});
    }

    const currentField = fields[0];
    // 按当前字段分组
    const grouped = items.reduce((acc, item) => {
      const key = item[currentField];
      acc[key] ??= [];
      acc[key].push(item);
      return acc;
    }, {});

    // 递归处理剩余分组字段
    return Object.fromEntries(
      Object.entries(grouped).map(([key, groupItems]) => [
        key,
        groupAndSum(groupItems, fields.slice(1))
      ])
    );
  };

  return groupAndSum(array, groupbyFields);
};

内容的提问来源于stack exchange,提问作者mike hennessy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:20:43