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

如何用JavaScript实现数组多键组合分组并对count字段求和

问题:生成所有键组合的聚合统计结果

原始数据

const results = [
  { make: "audi", fuel: "gasoline", model: "a1", count: 8 },
  { make: "audi", fuel: "diesel", model: "a3", count: 2 },
  { make: "audi", fuel: "gasoline", model: "a3", count: 5 }
];

目标结果

需要生成make、fuel、model所有可能的组合(包括部分键设为undefined的情况),并对count字段求和,最终得到如下结构:

const mappedResults = [
  { make: "audi", fuel: undefined, model: undefined, count: 8 + 2 + 5 },
  { make: "audi", fuel: "diesel", model: undefined, count: 2 },
  { make: "audi", fuel: "gasoline", model: undefined, count: 8 + 5 },
  { make: "audi", fuel: "gasoline", model: "a1", count: 8 },
  { make: "audi", fuel: "diesel", model: "a3", count: 2 },
  { make: "audi", fuel: "gasoline", model: "a3", count: 5 },

  { make: "audi", fuel: undefined, model: "a1", count: 8 },
  { make: "audi", fuel: undefined, model: "a3", count: 2 + 5 },

  { make: undefined, fuel: undefined, model: "a1", count: 8 },
  { make: undefined, fuel: undefined, model: "a3", count: 2 + 5 },

  { make: undefined, fuel: "gasoline", model: "a1", count: 8 },
  { make: undefined, fuel: "diesel", model: "a3", count: 2 },
  { make: undefined, fuel: "gasoline", model: "a3", count: 5 },

  { make: undefined, fuel: "gasoline", model: undefined, count: 8 + 5 },
  { make: undefined, fuel: "diesel", model: undefined, count: 2 }
];

当前实现方式

我通过Lodash的groupBy、reduce等方法实现了需求,代码如下:

const groupedByMake = groupBy(results, "make");
const groupedByModel = groupBy(results, "model");
const groupedByFuel = groupBy(results, "fuel");
let groupedByMakeModel = {}
results.reduce(function (r, o) {
  var key = o.make + "-" + o.model;

  if (!groupedByMakeModel[key]) {
    groupedByMakeModel[key] = Object.assign({}, o); // 创建对象副本
    r.push(groupedByMakeModel[key]);
  } else {
    groupedByMakeModel[key].count += o.count;
  }

  return r;
}, []);

let groupedByMakeFuel = {}
results.reduce(function (r, o) {
  var key = o.make + "-" + o.fuel;

  if (!groupedByMakeFuel[key]) {
    groupedByMakeFuel[key] = Object.assign({}, o); // 创建对象副本
    r.push(groupedByMakeFuel[key]);
  } else {
    groupedByMakeFuel[key].count += o.count;
  }

  return r;
}, []);

let groupedByModelFuel = {}
results.reduce(function (r, o) {
  var key = o.model + "-" + o.fuel;

  if (!groupedByModelFuel[key]) {
    groupedByModelFuel[key] = Object.assign({}, o); // 创建对象副本
    r.push(groupedByModelFuel[key]);
  } else {
    groupedByModelFuel[key].count += o.count;
  }

  return r;
}, []);

let groupedByMakeModelFuel = {}
results.reduce(function (r, o) {
  var key = o.make + "-" + o.model + "-" + o.fuel;

  if (!groupedByMakeModelFuel[key]) {
    groupedByMakeModelFuel[key] = Object.assign({}, o); // 创建对象副本
    r.push(groupedByMakeModelFuel[key]);
  } else {
    groupedByMakeModelFuel[key].count += o.count;
  }

  return r;
}, []);


const result = []

each(keys(groupedByMake), key => {
  return result.push({
    make: key,
    model: undefined,
    fuel: undefined,
    count: sumBy(groupedByMake[key], 'count')
  })
})
each(keys(groupedByModel), key => {
  return result.push({
    make: undefined,
    model: key,
    fuel: undefined,
    count: sumBy(groupedByModel[key], 'count')
  })
})
each(keys(groupedByFuel), key => {
  return result.push({
    make: undefined,
    model: undefined,
    fuel: key,
    count: sumBy(groupedByFuel[key], 'count')
  })
})

each(keys(groupedByMakeModel), key => {
  return result.push({
    make: groupedByMakeModel[key]?.make,
    model: groupedByMakeModel[key]?.model,
    fuel: undefined,
    count: groupedByMakeModel[key]?.count
  })
})

each(keys(groupedByMakeFuel), key => {
  return result.push({
    make: groupedByMakeFuel[key]?.make,
    model: undefined,
    fuel: groupedByMakeFuel[key]?.fuel,
    count: groupedByMakeFuel[key]?.count
  })
})

each(keys(groupedByModelFuel), key => {
  return result.push({
    make: undefined,
    model: groupedByModelFuel[key]?.model,
    fuel: groupedByModelFuel[key]?.fuel,
    count: groupedByModelFuel[key]?.count
  })
})

each(keys(groupedByMakeModelFuel), key => {
  return result.push({
    make: groupedByMakeModelFuel[key]?.make,
    model: groupedByMakeModelFuel[key]?.model,
    fuel: groupedByMakeModelFuel[key]?.fuel,
    count: groupedByMakeModelFuel[key]?.count
  })
})

console.log("result: ", result)

疑问

有没有更优、更高效的实现方式?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:15:42