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

如何基于两个条件对对象数组执行reduce合并计算?

对象数组合并问题求助

我需要基于choosenNum和game两个字段合并对象数组,将相同字段组合的对象的count求和,替换原count值。

原始数组

const gamesAndChoosenNumbers = [
  {
    choosenNum: '15',
    count: 10,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '15',
    count: 5,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '16',
    count: 20,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '16',
    count: 20,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '16',
    count: 10,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '150',
    count: 10,
    game: 'SUPER',
    gameCode: 'super',
  },
  {
    choosenNum: '150',
    count: 10,
    game: 'SUPER',
    gameCode: 'super',
  },
  {
    choosenNum: '155',
    count: 20,
    game: 'SUPER',
    gameCode: 'super',
  },
  {
    choosenNum: '155',
    count: 20,
    game: 'SUPER',
    gameCode: 'super',
  },
  {
    choosenNum: '200',
    count: 10,
    game: 'BOX',
    gameCode: 'box',
  },
  {
    choosenNum: '200',
    count: 10,
    game: 'BOX',
    gameCode: 'box',
  },
  {
    choosenNum: '155',
    count: 20,
    game: 'BOX',
    gameCode: 'box',
  },
];

期望结果

const mergedGamesAndChoosenNumbers = [
  {
    choosenNum: '15',
    count: 15,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '16',
    count: 50,
    game: 'AB',
    gameCode: 'double',
  },
  {
    choosenNum: '150',
    count: 20,
    game: 'SUPER',
    gameCode: 'super',
  },
  {
    choosenNum: '155',
    count: 40,
    game: 'SUPER',
    gameCode: 'super',
  },
  {
    choosenNum: '200',
    count: 20,
    game: 'BOX',
    gameCode: 'box',
  },
  {
    choosenNum: '155',
    count: 20,
    game: 'BOX',
    gameCode: 'box',
  },
];

尝试的代码(未解决问题)

const duplicateElementa = gamesAndChoosenNumbers.reduce((x, y, i) => {
  console.log({ i, x, y });
  if (x.map((it) => it.choosenNum).includes(y.choosenNum)) {
    console.log({ i1: i, x1: x[i - 1], y1: y });
    if (x[i - 1].game === y.game) {
      return [...x, { ...y, count: x[i - 1]?.count + y.count }];
    }
  } else {
    return [...x, y];
  }
}, []);

const nondupes = gamesAndChoosenNumbers.filter(
  (it) => !dupeNums.includes(it.choosenNum),
);
const dupesMerged = duplicateElementa.map((it, i, arr) => {
  const gt = arr.sort((a, b) => b.count - a.count);
  const st = gt.reduce((x, y, i, carr) => {
    if (
      x.map((it) => it.choosenNum).includes(y.choosenNum) &&
      x.map((it) => it.game).includes(y.game)
    ) {
      return x;
    } else {
      return [...x, y];
    }
  }, []);

  return st;
})[0];

const final: [] = dupesMerged
  .filter((it) => {
    console.log(nondupes.map((u) => u.choosenNum).includes(it.choosenNum));
    if (!nondupes.map((u) => u.choosenNum).includes(it.choosenNum)) {
      return it;
    }
  })
  .concat(nondupes);

问题出在当choosenNum为155出现在不同game分组时,合并逻辑错误,无法正确区分不同game下的同一choosenNum。


解决方案

核心思路是用reduce构建一个以choosenNum + game为键的对象,累计求和count,最后将对象的值转为数组即可:

const merged = Object.values(gamesAndChoosenNumbers.reduce((acc, curr) => {
  // 用choosenNum和game拼接成唯一键,区分不同分组
  const key = `${curr.choosenNum}-${curr.game}`;
  if (acc[key]) {
    // 已存在分组则累加count
    acc[key].count += curr.count;
  } else {
    // 不存在则复制当前对象存入累加器
    acc[key] = { ...curr };
  }
  return acc;
}, {}));

console.log(merged);

代码说明

  • 用choosenNum和game拼接成唯一标识的键,确保同一choosenNum在不同game下被视为独立分组
  • 遍历数组时,若键已存在则累加count,否则将当前对象存入累加器
  • 最后用Object.values()将累加器对象转为数组,直接得到合并后的结果

这个方案逻辑简洁,时间复杂度为O(n),能正确处理所有分组场景,包括同一choosenNum对应不同game的情况。


内容的提问来源于stack exchange,提问作者Ali-D-Coded

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:40:41