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

arr.reduce方法返回值疑问:为何代码返回数组最后一项而非累加器(数组转键值对象实现场景)

Why does my Array.reduce implementation return the last item instead of the accumulator?

Great question—let’s break down exactly what’s happening here, step by step.

First, a quick recap of how Array.reduce works: it loops through each element in your array, passing two core values to your callback function: the accumulator (the object/value you’re building up over iterations) and the current element. Whatever your callback returns becomes the accumulator for the next iteration, and the final accumulator is what reduce spits out as its result.

The Root of Your Bug

Your incorrect implementation uses an arrow function with an implicit return:

function groupByid(arr){
  return arr.reduce(
    (obj, value) => obj[value.id] = value, {}
  );
}

The critical detail here is that assignment expressions return the value being assigned, not the object you’re assigning to. So when you write obj[value.id] = value, this line evaluates to value itself—not the obj accumulator you’re trying to build.

Let’s walk through each iteration to see the domino effect:

  1. First iteration: obj starts as the empty {}. You assign obj['john'] = {id: 'john', ...}, and the callback returns this John user object (not the obj container).
  2. Second iteration: Now the accumulator is no longer the empty object—it’s the John user object. You try to assign obj['ann'] = {id: 'ann', ...} (but obj is now a user object, not a container!), and the callback returns the Ann user object.
  3. Third iteration: The accumulator is the Ann user object. Assign obj['pete'] = {id: 'pete', ...}, return the Pete user object.
  4. Final result: reduce returns the last value the callback returned—the Pete user object.

Why the Correct Code Works

Your working implementation uses curly braces around the callback logic, which forces you to explicitly return the accumulator:

function groupByid(arr){
  return arr.reduce(
    (obj, value) => {
      obj[value.id] = value;
      return obj; // This line makes all the difference!
    }, {}
  );
}

By returning obj after each assignment, you ensure the accumulator stays the container object through every iteration. Each loop modifies the same object and passes it along, resulting in the full key-value map you expect.

A Simplified Demo to Drive It Home

Here’s a tiny example that shows the difference clearly:

// Wrong: returns 3, not the built object
console.log([1,2,3].reduce((acc, val) => acc[val] = val, {})); 

// Right: returns {1:1, 2:2, 3:3}
console.log([1,2,3].reduce((acc, val) => {
  acc[val] = val;
  return acc;
}, {}));

Key Takeaway

Arrow functions with a single expression implicitly return that expression’s result. When that expression is an assignment, you get the assigned value back—not the object you modified. Always explicitly return the accumulator in your reduce callback when building up an object or array, unless you intentionally want to pass a different value to the next iteration.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 09:42:31