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

使用Array.reduce()按状态分组Todos数组时仅保留单条数据的问题排查

问题分析与解决方案

嘿,你的问题很典型——问题出在你用对象合并的方式处理同状态的 todos,而不是把它们收集到数组里!

错误原因拆解

你当前的reduce回调里写的是:

return { ...acc, [todo.status]: { ...acc[todo.status], ...todo } };

这里每次遇到同状态的todo时,你是用对象扩展语法把新todo覆盖到之前的对象上(比如completed属性每次都会被新的todo对象替换),而不是把todo添加到数组里,所以最后completed只会保留最后一条数据。

修正后的代码

我们需要把每个状态对应的初始值设为空数组,然后每次把当前todo追加到对应数组中:

const todos = [
  { id: 'a', name: 'Buy dog', action: 'a', status: 'deleted' },
  { id: 'b', name: 'Buy food', tooltip: null, status: 'completed' },
  { id: 'c', name: 'Heal dog', tooltip: null, status: 'completed' },
  { id: 'd', name: 'Todo this', action: 'd', status: 'completed' },
  { id: 'e', name: 'Todo that', action: 'e', status: 'todo' },
];

const groupedTodos = todos.reduce((acc, todo) => {
  // 先获取当前状态对应的数组,没有的话就用空数组
  const currentItems = acc[todo.status] || [];
  // 返回新的对象,对应状态的数组追加当前todo
  return {
    ...acc,
    [todo.status]: [...currentItems, todo]
  };
}, {});

console.log(groupedTodos);

为什么这样可行?

  • 初始化的累加器acc是一个空对象
  • 每次处理todo时,先取出该状态已有的数组(如果没有就用[])
  • 用扩展运算符创建新数组,把当前todo加进去,避免修改原数组(保持immutable)
  • 最后返回新的累加器对象,确保每个状态对应的都是包含所有同状态todo的数组

运行这段代码后,就能得到你期望的结果:

{
  "deleted": [{"id": "a", "name": "Buy dog", "action": "a", "status": "deleted"}],
  "completed": [
    {"id": "b", "name": "Buy food", "tooltip": null, "status": "completed"},
    {"id": "c", "name": "Heal dog", "tooltip": null, "status": "completed"},
    {"id": "d", "name": "Todo this", "action": "d", "status": "completed"}
  ],
  "todo": [{"id": "e", "name": "Todo that", "action": "e", "status": "todo"}]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:04:07