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

React+TypeScript中合并相同游戏数据项的优化方案咨询

改进React/TypeScript中合并tile数据函数的思路

问题背景

我在React/TypeScript项目里实现一个功能:从接口获取包含key、value、quantity等字段的JSON数据,渲染成网格tiles;用户点击tile时,将该项加入gameData数组用于列表展示,重复点击同一项时需要合并数据——quantity累加、value累加。

现有数据结构示例:

const apiData = [ 
  {key: 'A', value: 50, quantity: 1, color: '#3498db', ...etc}, 
  {key: 'B', value: 40, quantity: 1, color: '#e67e22', ...etc}, 
  ... 
]
const gameData = [ 
  {key: 'A', value: 200, quantity: 4, color: '#3498db', ...etc}, 
  {key: 'E', value: 10, color: '#fa0', ...etc}, 
]

我用Array.reduce写了一个groupBy函数实现合并逻辑,功能正常,但觉得还有优化空间,想请教有哪些改进思路?

我的现有实现:

export function groupBy(array: GameData[]) {
  const group: GameData[] = Object.values(
    array.reduce((acc: any, { value, quantity, ...r }) => {
      const key = Object.entries(r).join("-");
      acc[key] = acc[key] || { ...r, quantity: 0, value: 0 };
      return ((acc[key].value += value), (acc[key].quantity += 1)), acc;
    }, {})
  );
  return group;
}

几个实用的优化方向

1. 用天然唯一标识替代拼接key

你现在用剩余属性r的所有键值对拼接成分组key,存在潜在风险:如果r里有包含-的字段值,或者后续接口字段顺序调整,都会导致key失效。而数据里的key字段(比如'A'、'B')本身就是天然的唯一标识,直接用它作为分组key更高效可靠:

export function mergeGameDataItems(array: GameData[]) {
  return Object.values(
    array.reduce((acc: Record<string, GameData>, item) => {
      const existingItem = acc[item.key];
      if (existingItem) {
        // 注意:原来的quantity +=1 是固定加1,改成累加item的quantity更通用(适配api返回quantity>1的情况)
        existingItem.quantity += item.quantity;
        existingItem.value += item.value;
      } else {
        acc[item.key] = { ...item }; // 直接拷贝原item,省去解构开销
      }
      return acc;
    }, {})
  );
}

2. 消除any类型,强化TypeScript类型安全

原代码里的acc: any会丢失类型检查,换成Record<string, GameData>可以让编译器帮你提前发现类型错误,代码更健壮:

// 假设GameData是你定义的类型,直接用Record<string, GameData>作为累加器类型
export function mergeGameDataItems(array: GameData[]) {
  return Object.values(
    array.reduce((acc: Record<string, GameData>, item) => {
      // ... 逻辑同上
    }, {})
  );
}

3. 减少不必要的性能开销

原代码中的{ value, quantity, ...r }解构、Object.entries(r).join("-")拼接都是额外的性能消耗,尤其是数据量较大时。直接使用item.key作为分组key,能省去这些冗余操作,提升运行效率。

4. 函数命名更具语义化

groupBy这个名字太通用,换成mergeGameDataItems或者aggregateTileSelections,能让其他开发者一眼看懂函数的功能,提升代码可读性和维护性。

5. 适配Immutable状态管理(可选)

如果你的gameData是用React状态管理(比如useState),且希望保持Immutable(不修改原对象),更新时要创建新对象而非直接修改现有对象,避免状态更新不触发的问题:

if (existingItem) {
  acc[item.key] = {
    ...existingItem,
    quantity: existingItem.quantity + item.quantity,
    value: existingItem.value + item.value
  };
} else {
  acc[item.key] = { ...item };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:32:32