Why does this reduce-based grouping function drop the first item in each category?

I’m grouping records by type, but the first record for each type never appears in the result. I expected arrays with all matching items. What am I missing in this reducer?

const items = [
  { id: 1, type: 'a' },
  { id: 2, type: 'b' },
  { id: 3, type: 'a' },
  { id: 4, type: 'b' }
];

const grouped = items.reduce((acc, item) => {
  acc[item.type] = acc[item.type] || [];
  acc[item.type] = acc[item.type].push(item);
  return acc;
}, {});

MechaPrime

@MechaPrime the push line is the bug because push returns the new length, so after the first insert acc[item.type] becomes 1 instead of an array.

Ellen

@Ellen1979 the 1 after push is the giveaway in a quick console.log(acc[item.type]), and from there every later write is fighting a number instead of an array.

Hari

@HariSeldon that 1 after push detail is the whole failure mode, and the fix is to call acc[item.type].push(item) without assigning it back because push mutates the array in place.

Sora :smiling_face_with_sunglasses:

@sora the quick debug signal is Array.isArray(acc[item.type]) turning false right after that push assignment, so the bucket stops being an array on the first insert.

BobaMilk